Sorry for the newb question. I am reading the SafeMath code and it seems that it just does some multiplications and calculations?
How do you use it to protect your code? Do you just import it?
openzeppelinsolidity
Sorry for the newb question. I am reading the SafeMath code and it seems that it just does some multiplications and calculations?
How do you use it to protect your code? Do you just import it?
From Library contract method failing #2831:
You probably run geth with the --dev option to create a private network? In that case use the init subcommand to create a private chain. Instructions can be found in the wiki. Or use the testnet.
The problem is that this code uses the delegatecall which is added in the homestead release. The --dev flag uses the homestead block number of the mainnet which is 1150000. Any transaction before this block will encounter an invalid opcode, consumes all gas and all state changes are reverted.
To work around this issue:
...
The genesis config file supports a config section. Currently the only thing you can configure is the homestead block number. If you don't specify it, it will be defaulted to the mainnet number which is 1150000. So basically your contract will work after this block.
Try the following genesis file:
{ "config":{ "homesteadBlock":"5" }, "nonce":"0x0000000000000042", "timestamp":"0x0", "parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000", "extraData":"0x0", "gasLimit":"0x8000000", "difficulty":"0x400", "mixhash":"0x0000000000000000000000000000000000000000000000000000000000000000", "coinbase":"0x3333333333333333333333333333333333333333", "alloc":{ }
}
If the contract is deployed in block <5 it will give the gas limit problem.
Deployed in block >= 5 it should work as intended.
Further information on using the genesis file can be found at geth init, what are the arguments?.
I have set up my private blockchain using the following procedures:
Wocket:ESE bok$ more genesis.json
{
"config": {
"homesteadBlock": 10
},
"nonce": "0",
"difficulty": "0x400",
"mixhash": "0x00000000000000000000000000000000000000647572616c65787365646c6578",
"coinbase": "0x0000000000000000000000000000000000000000",
"timestamp": "0x00",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"extraData": "0x",
"gasLimit": "0x3B4A1B44",
"alloc": {}
}
I created a password file testpassword
containing my account password
I created a script to initialise my blockchain:
Wocket:ESE bok$ more 02_runGethGenesisInit
#!/bin/sh
geth --datadir /Users/bok/ESE/gethgenesis init /Users/bok/ESE/genesis.json
geth --datadir /Users/bok/ESE/gethgenesis --password testpassword account new
And I used chmod 700 02_runGethGenesisInit
to set the executable bit.
I created a script to start my private geth
node in mining mode:
Wocket:ESE bok$ more 02_runGethGenesis
#!/bin/sh
geth --datadir /Users/bok/ESE/gethgenesis --unlock 0 --password /Users/bok/ESE/testpassword --rpc --rpccorsdomain '*' --mine --minerthreads 1 console
And I used chmod 700 02_runGethGenesis
to set the executable bit.
I downloaded Browser Solidity from https://github.com/ethereum/browser-solidity/tree/gh-pages.
I unzipped the files and loaded index.html
into my web browser.
I initialised my blockchain data using the following command:
Wocket:ESE bok$ ./02_runGethGenesisInit
I started my node using the following command, and have been running it for a while:
Wocket:ESE bok$ ./02_runGethGenesis
...
I1015 09:56:14.364062 miner/worker.go:342] ๐จ Mined block (#5210 / f881b1be). Wait 5 blocks for confirmation
I1015 09:56:14.364333 miner/worker.go:539] commit new work on block 5211 with 0 txs & 0 uncles. Took 281.474ยตs
I1015 09:56:14.364360 miner/worker.go:435] ๐จ ๐ Mined 5 blocks back: block #5205
I1015 09:56:14.364492 miner/worker.go:539] commit new work on block 5211 with 0 txs & 0 uncles. Took 114.592ยตs
I1015 09:56:16.394886 miner/worker.go:342] ๐จ Mined block (#5211 / 420c7edc). Wait 5 blocks for confirmation
I1015 09:56:16.395189 miner/worker.go:539] commit new work on block 5212 with 0 txs & 0 uncles. Took 262.993ยตs
I1015 09:56:16.395222 miner/worker.go:435] ๐จ ๐ Mined 5 blocks back: block #5206
I loaded the test script by @TjadenHess
from How could I update default homesteadBlock value on my private Ethereum blockchain? into Solidity Browser:
contract TestHomestead{
function test () returns(bool){
return address(4).delegatecall(1);
}
}
I connected Solidity Browser to my local private node by clicking on the block icon and selecting Web3 Provider. I then clicked on Create to deploy the contract above to the blockchain. I clicked test and the message Transaction cost: 21657 gas.
shows that my blockchain is in Homestead mode.
Note: If I alter the function to make it a constant function test () constant returns(bool){
, I get the following results for a Homestead mode blockchain - true:
See section 9. below for the message displayed when the blockchain is in non-Homestead mode.
I've modified the library call source code slightly to make the value
variable public, and loaded this into Browser Solidity :
library Library {
function func () constant returns (uint8) {
return 5;
}
}
contract Contract {
uint8 public value;
function call_library_function () {
value = Library.func();
}
}
I clicked Create to deploy the code, call_library_function to execute the method, and value to view the library call function result:
The message Transaction cost: 41914 gas.
and the value of value
shows that the library function call succeeded.
I connected Browser Solidity with a geth --dev
blockchain:
geth --dev --datadir /Users/bok/ESE/gethdata --unlock 0 --password /Users/bok/ESE/testpassword --rpc --rpccorsdomain '*' --mine --minerthreads 1 console
I ran the same Homestead test code to produce the message Gas required exceeds limit: 50000000 showing that this --dev
blockchain is in non-Homestead mode:
Note: If I alter the function to make it a constant function test () constant returns(bool){
, I get the following results for a non-Homestead mode blockchain - false:
You need to install the OpenZeppelin npm package into your project directory via yarn or npm like:
yarn add @openzeppelin/contracts
or
npm install --save @openzeppelin/contracts
Then import the SafeERC20.sol
from those installed packages like:
import "@openzeppelin/contracts/<route to file>/SafeERC20.sol";
Then, you'll need to use it for IERC20
like:
using SafeERC20 for IERC20;
You don't need to import OpenZeppelin's Address.sol
. If it's a dependency for IERC20
, it will already be imported implicitly when you import SafeERC20.sol
.
Best Answer
Functions of
SafeMath
check logic conditions of math operations.Three steps are required to correctly implement SafeMath in your contract:
Declare that you wish to attach the library functions to the
uint256
type:using SafeMath for uint256;
Replace each of the standard arithmetic operators in your code with the equivalent call to a SafeMath function:
a + b
becomesa.add(b)
a - b
becomesa.sub(b)
a * b
becomesa.mul(b)
a / b
becomesa.div(b)
If you omit the last step, as seems to be quite common when people are first starting out with smart contracts, then your code receives no protection whatsoever from overflows/underflows. It is just the same as if you had not included SafeMath at all. This can be verified by testing the following code:
Even though the library has been imported, and the
using
statement declared, calling the first function will still return the enormously large integer value115792089237316195423570985008687907853269984665640564039457584007913129639935
, or hexFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
, whereas the second function will correctly throw an exception to prevent the underflow.