• gas • every function comprised of many operations and there’s a price to every type of operation • there’s a fixed amount of gas cost to function you design and you have to pay for it
Trang 1ethereum smart contract
林修平
Trang 2online compiler
• online compiler :
https://ethereum.github.io/browser-solidity/
Trang 3MANUAL COMPILE(using geth)
• connect to console
• set up a chain
• connect to main chain:go-ethereum/build/bin/geth console
• connect to testnet:go-ethereum/build/bin/geth testnet console
• build a private net:go-ethereum/build/bin/geth datadir “ your_directory " rpc rpcport port rpccorsdomain "*" port "30303" nodiscover
ipcapi "admin,db,eth,debug,miner,net,shh,txpool,personal,web3" rpcapi
"db,eth,net,web3" autodag networkid number nat "any" console
Trang 4MANUAL COMPILE(using geth)
• in console
• var contractABI = web3.eth.contract([{contractABI}]);
• var contract123 = contractABI.new(
parameters,{from: address,data: bytecode,gas: gas
}, callback_function)
Trang 5Quick Intro
Trang 6• price unit:ether
• address:you can withdraw from or save ether to it.
• it can represent an user account
• no code
• or represent a contract
• tied with a code
• NOTE: same code on different address is different contract
Trang 7• contract: comprised of state and function
• state: used by user to keep information regarding the contract
• function: change state of a contract
• NOTE: Ethereum discourage users from using state to preserve information, so it cost a lot of gas to either
create or change the state.
• WHY? Since every node(miner) needs to keep a full copy of the blockchain, they have to be compensated for storage cost of every contract.
• gas
• every function comprised of many operations and there’s a price to every type of operation
• there’s a fixed amount of gas cost to function you design and you have to pay for it when you want to execute a function
• you can decide how much ether you want to pay per gas and that becomes transaction fee needed for this
execution
Quick Intro
Trang 8• If you are on a public chain, every storage cost matters.
• But what if you are on a private chain?
• you can have ether as many as you want so you don’t need to worry about transaction fee
• but does it mean that you can use as many storage as you want?
• YES! but still, the costs of storing these states are to be taken by all nodes in your private chain
Quick Intro
Trang 9How it work
Trang 10• state
to make your contract work
How it work
Trang 11contract Count123{
uint counts(0) ;
function incre(){
counts = count + 1; }
}
Transaction(Deploy)
Trang 13How it work
Transaction(Invoke) Count123.incre()
Trang 14let’s take slock.it for example and write a simple bike renting contract!
slock.it
How it work
Trang 15state declaration
Trang 16contract bikeRenting {
address public owner;
address public currentRenter;
uint public expireTime;
…}
Trang 17• type , visibility , variable_name
state declaration
contract bikeRenting {
address public owner;
address public currentRenter;
uint public expireTime;
…}
Trang 18• type , visibility , variable_name
• type : bool, int, uint, address, mapping, bytes, string, struct
• visibility : public or private(default)
• public: accessible externally
(declare in your contract) uint public totalCount = 3;
(access in a console) mycontract.totalCount(); //3(access from other contract) thatcontract.totalCount() //3
• variable_name
state declaration
Trang 19• Array in solidity :
• address[] owners; address[3] threeOwners;
• push item into array: owners.push(address)
• delete item: delete owners[2]
• pitfall: only changes the value of specified item to zero instead of erase the item
state declaration
Trang 20• mapping :
• mapping(typeA => typeB) variable_name;
• example
• declare a mapping:
• mapping(address => uint) deposits;
• map address 0x123456789abcdef to integer 10:
• deposits[0x123456789abcdef] = 10;
• uninitialized or undeclared values are zero instead of NULL
• NOTE: there’s no NULL in Solidity
state declaration
Trang 21• Units and Globally available variables
• Ether unit:ether、finney、wei
• time unit:seconds、weeks、years、now
• now: present time
• more specifically, the time when this block is mined, i.e, the time_stamp parameter in the block header
state declaration
Trang 22• Special variables and functions
• msg: information regarding this transaction
• msg.sender: address who send the transaction
• msg.value: value sent with the transaction
• address related functions
• address.balance
• address.send(amount):send ether to address
state declaration
Trang 23• Special variables and functions
• throw
• reverts all changes made so far by the underlying transaction
• confiscate all gas provided by underlying transaction
state declaration
Trang 24initialization
Trang 25contract bikeRenting {
address public owner;
address public currentRenter;
uint public expireTime;
uint public unitPrice;
function bikeRenting(uint _unitPrice){
Trang 26• constructor function
• it’s name is exactly the same as contract’s
• executed when the contract is been deployed to blockchain
• executed only once
• not necessary
initialization
Trang 27function
Trang 28contract bikeRenting {
address public owner;
address public currentRenter;
uint public expireTime;
uint public unitPrice;
function bikeRenting(uint _unitPrice){
… }
function rent() payable returns(bool){
if(currentRenter != 0x0) return false;
else{
if( (msg.value/1 ether) / unitPrice < 1) return false;
else { expireTime = now + 15 minutes * (msg.value/1 ether)/unitPrice;
currentRenter = msg.sender;
rentingRecord(msg.sender, now, (msg.value/1 ether)/unitPrice);
} }
}
}
check if it’s been rented
how much time you get
for one unit check if paid more than a unit price
function
how many ether per unit
Trang 29function functionName(parameter1, parameter2, …) returns(type) {
}
function
Trang 30• visibility of a function
• public(default)
• private: only accessible by this contract
• internal: only accessible by this contract and contracts inherited from this one
• external: exactly the opposite of internal
• payable:
• decide if people can send ether while they execute this function, in other words, if you create a transaction to execute this function, you will be able to send the transaction along with some ether only if this function is a payable function
function
Trang 31contract bikeRenting {
address public owner;
address public currentRenter;
uint public expireTime;
uint public unitPrice;
function bikeRenting(uint _unitPrice){…}
function rent() payable returns(bool){…}
function isInUse(bool ifWantToRent) payable returns(bool){
if( expireTime > now ) return true;
else{
currentRenter = 0x0;
if( ifWantToRent == true) rent();
} }
}
this function checks if the bike is rented
ifWantToRent is a parameter sent by person who execute this transaction, indicating if he/she wants to rent this bike not expired yet, it is rented
function
Trang 32• we have to make sure person who executes isInUse function has the priority to rent if the bike is available because he/she pays transaction fee to execute this function
• why we need someone else to check if the bike is been rented or not?
• because a smart contract is not a robot, it won’t execute a command actively
• it won’t lock the bike itself even time is up, it needs to be triggered
• but if there are more than two people execute the same function in the same time, there’s no guarantee on the order of the execution
• so we have to make sure person who gets to execute isInUse function first will have the priority to rent the bike because he/she pays for this execution
Trang 33contract bikeRenting {
address public owner;
address public currentRenter;
uint public expireTime;
uint public unitPrice;
function bikeRenting(uint _unitPrice){…}
function rent() payable returns(bool){…}
function isInUse(bool ifWantToRent) payable returns(bool){…}
function collectMoney() { if( msg.sender == owner){
owner.send(this.balance) ; }
} }
make sure only owner can
execute this function
function
Trang 34privilege
Trang 35• there’s no built-in mechanism to restrict execution privilege, you have to check if person who executes the function has the right to
Trang 36repetitive actions
Trang 37• modifier
• attach to modifier: function bar() foo1() {…}
• attach to multiple modifiers: function bar() foo1() foo2() foo3(){…}
Trang 38repetitive actions
Trang 39foo2after foo1after
Trang 40contract creation in a contract
Trang 42fallback function
Trang 43• it’s executed only when someone executes a function not existed in the contract or someone simply sends some ether to this contract
• not necessary
• pitfall:
• person who owns this contract gets to decide what to do in a fallback function
• if you simply sends some ether to this contract, you also have to pay for the execution of fallback function if there is one
function () {
… }
Trang 44pitfalls
Trang 45• throw when address.send() fails
• throw will revert all changes and confiscate all gas even if you are halfway there
for(uint i=0; i<investorsCount; i++) {
if( inverstors[i].send(100) == false )
throw;
}
Trang 46• throw when address.send() fails
• why address.send() fail?
• 1 out of gas
• supply enough gas
• 2 callstack
• 1024 layer
Trang 47• mitigation: use a withdraw pattern
• still, this solution leaves the problems mentioned to the msg sender
Trang 48… }
… }
function extCallable(){
do_something_on_shared_state … }
Trang 49fixed after compiler version 0.4.4
Trang 50• selfdestruct(recipient)
• terminate the contract, destroy code and storage, then transfer the remaining ether to recipient
• event: writes data into transaction receipt
• example: event paymentRecord(address indexed buyer , uint value )
• indexed: write data into topics field
• if data is more than 32 bytes, hash of data is written into topics instead
• transaction receipt
• data
• topics: can be used as a condition filter
Trang 51Misc
Trang 52• contract inheritance : contract Final is most-base-like, …, most-derived{…}
Misc
Trang 53• use delete on array to delete all elements
• vmdebug, verbosity
• targetgaslimit