how to read token sale smart contracts
@crypto_eli5code is the law in ethereum network. not everyone can code, but reading the code is not as scary as it seems. there are a few things you can learn by reading a smart contract. i'll walk you through request.network token sale contract code.
first, obtain the code from etherscan.io, open the contract source tab and grab the contract source code.
skip the standard library parts as they are always the same old crutches implementing standard token interface or even math. yup, ethereum can't do math properly and you need additional checks for overflows.
the function you are looking for has no name, it's simply function ()
, which is invoked when someone sends ether to this address without calling a specific function. it is often called the default or fallback function.
// fallback function can be used to buy tokens function () payable { buyTokens(); }
okay, nothing to see here. let's find function buyTokens()
// low level token purchase function // Request Modification : change to not mint but transfer from this contract function buyTokens() public payable { require(validPurchase()); uint256 weiAmount = msg.value; // calculate token amount to be created uint256 tokens = weiAmount.mul(rate); // update state weiRaised = weiRaised.add(weiAmount); require(token.transfer(msg.sender, tokens)); // Request Modification : changed here - tranfer instead of mintable TokenPurchase(msg.sender, weiAmount, tokens); forwardFunds(); }
require
will cancel the transaction and burn all provided gas if the inner clause is false
, let's find function validPurchase()
function validPurchase() internal returns(bool) { require(tx.gasprice <= GAS_LIMIT_IN_WEI); uint ethCapPerAddress = getCurrentEthCapPerAddress(); participated[msg.sender] = participated[msg.sender].add(msg.value); return super.validPurchase() && participated[msg.sender] <= ethCapPerAddress; }
here we can see another requirement which limits the maximum gas price. constant GAS_LIMIT_IN_WEI
value can be looked up here:
uint public constant GAS_LIMIT_IN_WEI = 50000000000 wei; // limit gas price -50 Gwei wales stopper
this basically tells us that no transaction with the gas price exceeding 50 gwei can pass. not sure if the project has anything against wales though.
the function also calls super.validPurchase()
, a namesake function in the parent contract.
function validPurchase() internal returns(bool) { bool withinPeriod = now >= startTime && now <= endTime; bool nonZeroPurchase = msg.value != 0; return withinPeriod && nonZeroPurchase; }
this function ensures that we are within the sale time window and that at least some ether was sent along with transaction. if you try to look up startTime
, you'll end up with nothing as it's not a constant, but a variable that is set when the contract is deployed. note that the function where it's set called exactly as the contract (RequestTokenSale
). such function is called a constructor function.
you can look up the contract state on etherscan on read smart contract tab.
startTime 1507878000 endTime 1508223600
if you see a number ~1.5 billion it's almost certainly a date-time written as unix time (sometimes called epoch time, a number of seconds passed from midnight january 1st, 1970). unix time is always in utc, so don't forget to convert to your local timezone.
startTime 2017-10-13 07:00:00 UTC endTime 2017-10-17 07:00:00 UTC
sometimes a sale is limited by block numbers and not by time. here's an example from another crowdsale.
presaleStartBlock 4241483 presaleUnlimitedStartBlock 4245055 crowdsaleStartBlock 4248627 crowdsaleEndedBlock 4348635
this way you can check for exact requirements even if the details are not provided publicly in full. for example tezos crowdsale was limited by block number and due to unpredictable nature of block times started 45 minutes early.
so, to wrap up:
- unwind the
function ()
to see the buying flow and participation requirements - look for constants in
ALL_CAPS
and find where they are used. you can get a deeper understanding of token distribution mechanics, vesting periods and the exact exchange rates. - look for contract state in read smart contract tab on etherscan
subscribe to @crypto_eli5