Skip to content

Commit

Permalink
scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
t4sk committed Feb 24, 2020
1 parent 108f3a7 commit 76e3dcc
Show file tree
Hide file tree
Showing 3 changed files with 311 additions and 0 deletions.
127 changes: 127 additions & 0 deletions video-scripts/call.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
```
pragma solidity ^0.5.11;
/*
call
- low level method available on address
- not recommended
- examples
- call existing function
- call non-existing function (trigger the fallback function)
*/
contract Receiver {
event Received(address caller, uint amount, string message);
// NOTE: external, payable
function () external payable {
// NOTE: cannot take input, cannot return output
emit Received(msg.sender, msg.value, "Fallback was called");
}
// NOTE: inputs
// NOTE: payable
// NOTE: outputs
function foo(string memory _message, uint _x) public payable returns (uint) {
emit Received(msg.sender, msg.value, _message);
// NOTE: output
return _x + 1;
}
}
contract Caller {
event Response(bool success, bytes data);
// NOTE: payable addr
function testCallFoo(address payable _addr) public payable {
// NOTE: value and gas optional
// NOTE: start with ("")
// NOTE: explain learn abi.encodeWithSignature
// explain signature
/*
- function name with the parenthesised
- list of parameter types
- Parameter types are split by a single comma
- no spaces are used
- no return type
(1 byte = 8 bits, 2**8, 256, hex = 0-9a-f 16 * 16 = 256)
*/
// explain function selector
// bytes4(keccak256(bytes(signature))
// NOTE: no space, no return type
// NOTE: going to call fallback if function signature is wrong
// NOTE: uint must be uint256
(bool success, bytes memory data) = _addr.call.value(msg.value).gas(5000)(
abi.encodeWithSignature("foo(string,uint256)", "call foo", 123)
);
emit Response(success, data);
}
// NOTE: remove payable addr
function testCallDoesNotExist(address _addr) public {
// NOTE: optional value and gas
(bool success, bytes memory data) = _addr.call(
abi.encodeWithSignature("doesNotExist()")
);
emit Response(success, data);
}
}
/*
DEMO
- deploy contracts
- callFoo
- NOTE: 2 logs
- NOTE: caller
- NOTE: success
- NOTE: return data == (x + 1) (parseInt("0x7c")
- NOTE: walk through code execution
- callDoesNotExist
- NOTE: 2 logs
- NOTE: caller
- NOTE: success
- NOTE: return data = 0
*/
```

```
pragma solidity ^0.5.11;
/*
call - low level method available on address type
examples
- call existing function
- call non-existing function (triggers the fallback function)
*/
contract Reciever {
event Received(address caller, uint amount, string message);
function () external payable {
emit Received(msg.sender, msg.value, "Fallback was called");
}
function foo(string memory _message, uint _x) public payable returns (uint) {
emit Received(msg.sender, msg.value, _message);
return _x + 1;
}
}
contract Caller {
function testCallFoo(address payable _addr) public payable {
_addr.call.value(msg.value).gas(5000)("");
}
}
```
51 changes: 51 additions & 0 deletions video-scripts/calling-other-contract.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
```
pragma solidity ^0.5.11;
/*
- call is low level function to call other functions and send ether
- examples
call non payable function in another contract
call payable function in another contract
- common way to call function and send ether
*/
contract Callee {
uint public x;
uint public value;
function setX(uint _x) public returns (uint) {
x = _x;
return x;
}
// NOTE: how to return multiple outputs
function setXandSendEther(uint _x) public payable returns (uint, uint) {
x = _x;
value = msg.value;
return (x, value);
}
}
contract Caller {
// NOTE: Callee input (address)
// TODO: what is the type of Callee?
function callSetX(Callee _callee, uint _x) public {
uint x = _callee.setX(_x);
}
// NOTE: payable
function callSetXAndSendEther(Callee _callee, uint _x) public payable {
// NOTE: fails to compiles if func does not exit or wrong parameters (unlike call)
// NOTE: assigning multiple outputs
(uint x, uint value) = _callee.setXandSendEther.value(msg.value)(_x);
}
}
/*
DEMO
NOTE: callee = address type
callSetX
callSetXAndSendEther
*/
```
133 changes: 133 additions & 0 deletions video-scripts/delegatecall.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
```
pragma solidity ^0.5.11;
/*
# intro
- delegatecall is a low level function similar to call.
- when A delegatecall B
runs B's code inside A's context (storage, msg.sender, msg.value)
- can upgrade contract A without changing any code inside it
# explain delegatecall context
# explain delegatecall upgrade
# code (contract B, A)
# demo
# code (change storage for contract B)
# demo
# code (contract B2)
# demo
# summary
- delegatecall runs code of callee in caller's context (storage, sender, value)
- upgrade contract without changing the code
- storage layout must be same
*/
contract B {
uint public num;
address public sender;
uint public value;
function setVars(uint _num) public payable {
num = _num;
sender = msg.sender;
value = msg.value;
}
}
contract B2 {
uint public num;
address public sender;
uint public value;
function setVars(uint _num) public payable {
num = 2 * _num;
sender = msg.sender;
value = msg.value;
}
}
contract A {
// NOTE: storage layout must be the same
uint public num;
address public sender;
uint public value;
function setVars(address _contract, uint _num) public payable {
// NOTE: function signature (similar to call)
// NOTE: uint256
(bool success, bytes memory data) = _contract.delegatecall(
abi.encodeWithSignature("setVars(uint256)", _num)
);
}
}
/*
DEMO
deploy B
deploy A
- setVars
- check state variables on contract A and B
- note sender and value
change B storage
- redeploy B
- setVars
- check A values
create B2
deploy B2
- setVars
- check state variables on contract A
*/
```

```
pragma solidity ^0.5.11;
/*
delegatecall
- a low level function similar to call
- when contract A delegatecall contract B
it runs B's code inside A's context (storage, msg.sender, msg.value)
- can upgrade contract A without changing any code inside it
*/
contract B {
uint public num;
address public sender;
uint public value;
function setVars(uint _num) public payable {
num = _num;
sender = msg.sender;
value = msg.value;
}
}
contract B2 {
uint public num;
address public sender;
uint public value;
function setVars(uint _num) public payable {
num = 2 * _num;
sender = msg.sender;
value = msg.value;
}
}
contract A {
uint public num;
address public sender;
uint public value;
function setVars(address _contract, uint _num) public payable {
(bool success, bytes memory data) = _contract.delegatecall(
abi.encodeWithSignature("setVars(uint256)", _num)
);
}
}
```

0 comments on commit 76e3dcc

Please sign in to comment.