### State Channel + Create2 #### Advanced Smart Contract
Yuet Loo Wong
### Topics - State Channel - Counterfactual - Create2 - EIP 1014
### Blockchain Scalability Problem One of the major problem with blockchain is scalability problem - Bitcoin:
7
tps - Ethereum:
15
tps - Visa:
47,000
transactions per second (tps)
### State Channel - A blockchain scaling solution - Conduct blockchain transactions off-chain - Uses cryptographic signatures - to allow secure, instantaneous transactions -
State channels by Jeff Coleman
### Payment Channel - A specific type of state channel - An
example
in solidity document - Uses cryptographic signatures - Make repeated transfers of Ether off-chain - Each message specifies total Ether owed
### Payment Steps - Alice funds a smart contract with Ether - This “opens” the payment channel - Alice signs payment messages to Bob - This is repeated for each payment - This is done off-chain - Bob “closes” the payment channel - This withdraws Ether
### Creating signatures - What to Sign - The amount to be transferred - Protection against replay attacks - contract address
### Create Signature (Javascript) ``` function signPayment(amount, contractAddress) { const digest = ethers.utils.solidityKeccak256( ["uint256", "address"], [amount, contractAddress] ); const arrayDigest = ethers.utils.arrayify(digest); const signature = wallet.signMessage(arrayDigest); return signature; } ```
### Verifying Signature (Contract) ``` function isValidSignature(uint256 amount, uint8 v, bytes32 r, bytes32 s) public view returns(bool) { // this recreates the message that was signed on the client bytes32 hash = keccak256(abi.encodePacked(amount, contractAddress)); bytes32 message = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); address signer = ecrecover(message, v, r, s); return( signer == sender); } ```
### Closing Channel - Bob closes the channel to receive funds - Bob uses last signed message to close channel - ``` function close(uint256 amount, uint8 v, bytes32 r, bytes32 s) public { require(msg.sender == recipient); require(isValidSignature(amount, v, r, s)); recipient.transfer(amount); selfdestruct(sender); } ```
### Channel Timeout - A way for Alice to recover escrowed funds - An expiration is set at contract creation - After expiry, Alice can recover fund - Bob cannot receive fund after channel closure - ``` function claimTimeout() public { require(now >= expiration); selfdestruct(sender); } ```
### Create2 - A low level way to create a contract - create2(v, p, n, s) - v is contract creation value in wei - p is the memory location of the contract code - n is the length of contract code - s is the salt -
EIP 1014 Skinny CREATE2
### Create2 Motivation Allows state channel interactions to be made with addresses that do not exist yet on-chain but can be relied on to eventually contain code
### Counterfactual Things that could happen on the blockchain, but don't
### Contract Address - If create is used, the contract address is: - keccak256(rlp([caller, nonce]))[12:] - If create2 is used, the contract address is: - keccak256(0xff + caller + salt + keccak256(init_code))[12:]
## Contract Code - need assembly to use extcodesize and extcodecopy ``` function GetCodeAt(address _addr) public view returns (bytes memory o_code) { assembly { let size := extcodesize(_addr) // code size o_code := mload(0x40) // free memory pointer mstore(0x40, add(o_code, and(add(add(size, 0x20), 0x1f), not(0x1f)))) mstore(o_code, size) // code length extcodecopy(_addr, add(o_code, 0x20), 0, size) // copy code } } ```
## Contract Hash - EXTCODEHASH -
Introduced by EIP-1052
- Openzepplin
isContract()
utility function - ``` function isContract(address account) internal view returns (bool) { bytes32 codehash; bytes32 accountHash = 0xc5d2...ad8045d85a470; assembly { codehash := extcodehash(account) } return (codehash != accountHash && codehash != 0x0); } ```