Ethereum Training

Serpent

Ethereum POC5 (well, almost...)

ethercasts

  • Serpent syntax pretty much like Python
  • Stand-alone compiler serpent
  • Compiler build into AlethZero, Ethereal, EthereumJ
  • Web based testing tool - mintchalk.com

wiki.ethereum.org

Serpent Wiki

Example: subcurrency.se


init:
    contract.storage[msg.sender] = 1000000
code:
    if msg.datasize == 1:
        addr = msg.data[0]
        return(contract.storage[addr])
    else:
        from = msg.sender
        fromvalue = contract.storage[from]
        to = msg.data[0]
        value = msg.data[1]
        if fromvalue >= value:
            contract.storage[from] = fromvalue - value
            contract.storage[to] = contract.storage[to] + value
            return(1)
        else:
            return(0)

Syntax

Program Structure


init:
    executed upon contract creation

shared:
    constants etc
code:
    contract body as stored in the block chain

Comments


x = 4 // this is a comment and does
      // not appear in the compiled code
      # can also comment with a hash like this
      /* this style is not supported however */


Arithmetic (1/2)

  • Normal arithmetic works as expected: x = 20 + 7 * 5 sets x to 55
  • Negative numbers do not exist: x = 0 - 1 sets x to 11579208923731619542357098500868790785326998466564 0564039457584007913129639935 (which is 2^256 - 1)
  • Decimals do not exist: x = 7 / 4 sets x to 1

Arithmetic (2/2)

  • You can use #/ and #% to pretend the numbers are signed integers: x = (0-9) #/ 3 + 5 sets x to 2, 
whereas y = (0-9) / 3 + 5 sets y to 38597363079105398474523661669562635951089994 888546854679819194669304376546647
  • Arithmetic wraps around 2^256: x = 3 ^ (2 ^ 254) sets x to 1
  • Use x = y | z, x = y & z and x = y xor z for bitwise operations

Variables / Arrays

  • Variables work just like any other language: x = 25 then y = x + 5 sets y to 30
  • Use x = array(n) to initialize an array of n 32-byte values

  • Use x[i] = v to set values in arrays and v = x[i] to get values in arrays

  • Use array literals to declare arrays inline: x = [1,2,3]

Byte arrays

  • Use x = bytes(n) to initialize a string/bytearray of n bytes

  • Use setch(x,i,v) to set the byte at position i of byte array x to value v
  • Use v = getch(x,i) to get the byte at position i of byte array x
  • Variables are stored in the EVM memory, you pay a fee for expanding its size.

Conditions and loops

  • if, elif, else and while like Python

if x > 5:
    y = 7

x = 248
while x > 1:
    if (x % 2) == 0:
        x = x / 2
    else:
        x = 3 * x + 1

Pseudovariables

Pseudovariables block

  • block.prevhash - previous block hash
  • block.number - block number
  • block.timestamp - block timestamp
  • block.difficulty - block difficulty
  • block.coinbase - address of block miner
  • block.gaslimit - maximum amount of gas that can be spent in the block

Pseudovariables tx

  • tx.gasprice - amount paid by transaction for gas
  • tx.origin - original sender of transaction (NOT the sender of the current message, which is different in a nested call situation)
  • tx.gas - current amount of gas remaining

Pseudovariables msg

  • msg.sender - sender of the message
  • msg.value - value of the message
  • msg.datasize - length of the data provided by the message, measured as the number of complete 32-byte chunks
  • msg.data[i] - the i-th 32-byte chunk in message data

Pseudovariables contract

  • contract.address - address of the contract
  • contract.balance - balance of the contract
  • contract.storage[i] - the contract's long term storage, at index i

Functions

Transactions

  • send(to, value) - sends value ether to to
  • send(gas, to, value) - same, allowing the computation the given amount of gas.
  • x = msg(gas, to, value, datastart, datalen) - sends a message to to, using the data at memory indices datastart...datastart+datalen*32-1, with the given amount of ether and gas, and sets x to the first 32 bytes of the result.
  • x = msg(gas, to, value, datastart, datalen, outputlen) - sends a message to to, using the data at memory indices datastart...datastart+datalen*32-1, with the given amount of ether and gas, and pastes outputlen times 32 bytes to the variable x

Contract creation

  • x = create(f) - creates a new contract using code from file f , and return the address of the contract
  • x = create(endowment, f) - same with endowment

Halting

  • stop - this keyword by itself on one line stops execution
  • return(x) - returns the 32 bytes of value x
  • return(memstart, len) - returns the memory at indices memstart ... memstart+32*len-1
  • suicide(a) - destroys the contract, sending all remaining balance to a

Miscellaneous

  • x = sha3(v) - returns the SHA3 of the given 32-byte value
  • x = byte(y,z) - sets x to the z-th byte of y
  • inset(f) - inline the content of another Serpent file

Simulators

mintchalk.com

mintchalk

evm-sim

evm-sim

What's next?

⇒ Try Serpent

Questions / Feedback?