How to do it...

  1. To write the assembly inline, use the assembly keyword:
assembly {
// assembly code
}
  1. Create local variables in the assembly by using the let keyword. For variables without any assignment, the default value will be assigned:
let x
let y := 2
  1. Access the variables that are defined outside the assembly directly:
function f(uint x) public {
assembly {
x := sub(x, 1)
}
}
Assigning values to variables that point to memory or storage work differently inside solidity assembly. The assignment will only change the pointer and not the data.
  1. Create a for loop in the assembly just like a regular loop:
assembly {
for { let i := 0 } lt(i, 10) { i := add(i, 1) } {
y := add(y, 1)
}
}
  1. Use the if statement to validate conditions inside the assembly. There is no else condition so use the switch statement for multiple conditions:
assembly {
if lt(x, 0) {
x := add(x, 1)
}
}
  1. Use the switch statement for executing statements based on conditions:
assembly {
switch x
case 0 {
y := add(x, 1)
}
case 1 {
y := add(x, 2)
}
default {
y := 0
}
}
  1. Make function calls in the assembly just like you do with the normal function call:
assembly {
function power(x, y) -> result {
switch y
case 0 {
result := 1
}
case 1 {
result := x
}
default {
result := power(mul(x, x), div(y, 2))
switch mod(y, 2)
case 1 {
result := mul(x, result)
}
}
}
}
  1. Try using functional-style opcodes inside the assembly:
assembly {
let x := add(1, 2)
let y := mul(x, 3)
}
  1. Some of the supported functional opcodes are listed here. The complete list is available in the Ethereum yellow paper:
  • stop: stop execution
  • add(x,y), sub(x,y), mul(x,y), div(x,y): Arithmetic operations
  • mod(x,y): x % y
  • exp(x,y): x to the power of y
  • not(x): Negation of x
  • lt(x,y), gt(x,y): Less than or greater than; 1 for true and 0 for false
  • eq(x,y): 1 for true and 0 for false
  • and(x,y), or(x,y), xor(x,y): Bitwise AND, OR, XOR
  • shl(x,y), shr(x,y): Logical shift left/right y by x bits 
  • jump(label): Jump to label/code position
  • pc: Current position in code
  • pop(x): Remove the element pushed by x
  • dup1...dup16: Copy the ith stack slot to the top
  • swap1...swap16: Swap the topmost and ith stack slot below it
  • mload(p): mem[p..(p+32)]
  • mstore(p,v): mem[p..(p+32)] := v
  • sload(p): storage[p]
  • sstore(p,v): storage[p] := v
  • msize: Size of memory
  • gas: Gas left for execution
  • address: Address of the current contract
  • balance(a): Balance in wei at address a 
  • caller: Transaction/call sender
  • callvalue: Value sent with the call
  • calldatasize: Size of the calldata in bytes
  • call, callcode, delegatecall, staticall: Call contract at given address
  • log0...log4: Log with topics and data
  • timestamp: Timestamp of the current block in seconds since the epoch
  1. Try using the instruction style opcodes inside the assembly. The opcodes can be listed in the same way as they will end up in the bytecode. The following example adds 10 to the contents in memory at position 0x80:
10 0x80 mload add 0x80 mstore
  1. Functional and instructional style expressions cannot be mixed together. They have to be written in either functional or instructional style:
mstore(0x80, add(mload(0x80), 10))
The order of arguments is in reverse order when comparing functional style and instruction style expressions. While using functional style expressions, the first argument will end up on the top of the stack.
  1. The assembly language described so far in this recipe can also be used as standalone assembly code. 

  1. The assembly code can be used to achieve functionalities that are not possible with plain solidity. One good example is to check whether an address belongs to a contract or is owned externally:
pragma solidity ^0.4.24;

/**
* Library contract with assembly code
*/
library AddressValidator {

/**
* Function to verify contract address
* @param _address Address to verify
* @returns isContract Returs verification result
*/
function _isContract(address _address) public
returns (bool isContract) {

// Variable to store the code size
uint codeSize;

assembly {
codeSize := extcodesize(_address)
}

isContract = codeSize > 0;
}
}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.138.35.255