ethereum examples
clist_code=""" | |
# A Capability List system | |
# | |
# Gronvetter introduction diagram | |
# Alice introduces Carol to Bob. | |
# | |
# Alice --[foo->]---> Bob | |
# // | |
# // | |
# Carol --\=--> | |
# | |
init: | |
# Initial state goes here! | |
code: | |
# Ignore a message while the contract is lcoked | |
if contract.storage[0] == 1: | |
stop() | |
# Create a new object | |
if msg.data[0] == 1: | |
parent = msg.sender | |
contract.storage[0] == 1 # Lock the contract before transferring control | |
child = create(msg.data[1], msg.data[2], msg.data[3], ...) # TODO: fix? | |
contract.storage[0] = 0 # unlock the contract | |
# Parenthood | |
contract.storage[[parent,child]] = 1 | |
# Grant a capability by introduction | |
if msg.data[0] == 2: | |
# Alice is the sender | |
sender = msg.sender | |
# Bob is the object | |
object = msg.data[1] | |
# Carol is the receiver | |
receiver = msg.data[2] | |
# To grant a capability, the sender must hold a capability | |
# to both the object and to the receiver | |
if !(contract.storage[[sender,object]] and | |
contract.storage[[sender,receiver]]): | |
return(1) | |
# Grant access | |
contract.storage[[receiver,object]] = 1 | |
# Check a capability | |
if msg.data[0] == 3: | |
# returns 1 if the capability is granted, 0 otherwise | |
return contract.storage[[msg.data[1],msg.data[2]]] | |
# Additional rule: | |
# A "top level" object with no | |
""" | |
check_example = """ | |
# Check if the sender has capability to check this object | |
if !call(${clist}, [3, msg.sender, this]): | |
stop() | |
... | |
""" | |
import serpent | |
from pyethereum import transactions, blocks, processblock, utils | |
processblock.print_debug = 1 | |
code = serpent.compile(contract_code) | |
key = utils.sha3('cow') | |
addr = utils.privtoaddr(key) | |
genesis = blocks.genesis({ addr: 10**18 }) | |
tx1 = transactions.contract(0,10**12,10000,0,code).sign(key) | |
result, contract = processblock.apply_transaction(genesis,tx1) |
contract_code = """ | |
// Reentrant contract | |
command = msg.data[0] | |
if command == 1: | |
contract.storage[0] = 99 | |
contractToCall = msg.data[1] | |
params = [2] | |
#msg(200, contractToCall, 0, params, 1) | |
if contract.storage[0] != 99: | |
suicide() | |
if command == 2: // option 2 | |
contract.storage[0] = -1 | |
""" | |
import serpent | |
from pyethereum import transactions, blocks, processblock, utils | |
processblock.print_debug = 1 | |
code = serpent.compile(contract_code) | |
key = utils.sha3('cow') | |
addr = utils.privtoaddr(key) | |
genesis = blocks.genesis({ addr: 10**18 }) | |
tx1 = transactions.contract(0,10**12,10000,0,code).sign(key) | |
result, contract = processblock.apply_transaction(genesis,tx1) | |
#print genesis.to_dict() | |
tx2 = transactions.Transaction(1,10**12,2000,contract,0, | |
serpent.encode_datalist([1,contract])).sign(key) | |
result, ans = processblock.apply_transaction(genesis,tx2) | |
print 'result:', serpent.decode_datalist(ans) | |
#print genesis.to_dict() |
contract_code = """ | |
// Locked contract | |
if contract.storage[100] == 1: | |
stop # Don't enter a contract that's locked | |
contract.storage[100] = 1 # Lock the contract | |
command = msg.data[0] | |
if command == 1: | |
contract.storage[0] = 99 | |
contractToCall = msg.data[1] | |
params = [2] | |
msg(200, contractToCall, 0, params, 1) | |
if contract.storage[0] != 99: | |
suicide() | |
if command == 2: // option 2 | |
contract.storage[0] = -1 | |
contract.storage[100] = 0 # Unlock | |
return(0) | |
""" | |
import serpent | |
from pyethereum import transactions, blocks, processblock, utils | |
processblock.print_debug = 1 | |
code = serpent.compile(contract_code) | |
key = utils.sha3('cow') | |
addr = utils.privtoaddr(key) | |
genesis = blocks.genesis({ addr: 10**18 }) | |
tx1 = transactions.contract(0,10**12,10000,0,code).sign(key) | |
result, contract = processblock.apply_transaction(genesis,tx1) | |
#print genesis.to_dict() | |
tx2 = transactions.Transaction(1,10**12,10000,contract,0, | |
serpent.encode_datalist([1,contract])).sign(key) | |
result, ans = processblock.apply_transaction(genesis,tx2) | |
print 'result:', serpent.decode_datalist(ans) | |
#print genesis.to_dict() |
namecoin_code = """ | |
// Namecoin | |
if !contract.storage[msg.data[0]]: # Is the key not yet taken? | |
# Then take it! | |
contract.storage[msg.data[0]] = msg.data[1] | |
return(1) | |
else: | |
return(0) // Otherwise do nothing | |
""" | |
import serpent | |
from pyethereum import transactions, blocks, processblock, utils | |
processblock.print_debug = 1 | |
code = serpent.compile(namecoin_code) | |
key = utils.sha3('cow') | |
addr = utils.privtoaddr(key) | |
genesis = blocks.genesis({ addr: 10**18 }) | |
tx1 = transactions.contract(0,10**12,10000,0,code).sign(key) | |
result, contract = processblock.apply_transaction(genesis,tx1) | |
print genesis.to_dict() | |
tx2 = transactions.Transaction(1,10**12,10000,contract,0, | |
serpent.encode_datalist(['george',45])).sign(key) | |
result, ans = processblock.apply_transaction(genesis,tx2) | |
serpent.decode_datalist(ans) | |
print genesis.to_dict() |
contract_code = """ | |
// | |
// A message queue contract | |
init: | |
contract.storage[0] = 0 # Starts unlocked | |
contract.storage[1] = 3 # Queue head | |
contract.storage[2] = 3 # Queue tail | |
code: | |
command = msg.data[0] | |
if command == 1: # Append to queue | |
error = 0 | |
tail = contract.storage[2] | |
# First element is a contract address | |
contract = msg.data[1] | |
# Second element is gas price | |
gasprice = msg.data[2] | |
# Third element is gas cost | |
gascost = msg.data[3] | |
# Fourth element is value | |
value = msg.data[4] | |
# Fifth element is argument data | |
argument = msg.data[5] | |
# Assign a fixed fee for whoever *executes* this transaction | |
fee = 200 | |
# Check that the msg value is enough | |
if msg.value < gascost + value + fee: | |
return(1) # Insufficient value | |
# Push this message to the end of the queue | |
contract.storage[tail*5+0] = contract | |
contract.storage[tail*5+1] = gasprice | |
contract.storage[tail*5+2] = gascost | |
contract.storage[tail*5+3] = value | |
contract.storage[tail*5+4] = argument | |
contract.storage[2] += 1 | |
return(0) | |
if command == 2: # Execute the front of queue | |
# CRITICAL SECTION - Shouldn't be reentrant | |
# Don't enter a contract that's locked | |
if contract.storage[0] == 1: | |
return(1) | |
# Lock the contract | |
contract.storage[0] = 1 | |
head = contract.storage[1] | |
tail = contract.storage[2] | |
if head >= tail: # The queue is empty, nothing to execute | |
contract.storage[0] = 0 | |
return(2) | |
contract = contract.storage[head*5+0] | |
gasprice = contract.storage[head*5+1] | |
gascost = contract.storage[head*5+2] | |
value = contract.storage[head*5+3] | |
argument = contract.storage[head*5+4] | |
# Check the gas price is low enough | |
if tx.gasprice > gasprice: | |
contract.storage[0] = 0 | |
return(3) # Wrong gas price | |
# Check the gas is sufficient to finish the transaction | |
if tx.gas < gascost + 200 # (remainder) | |
contract.storage[0] = 0 | |
return(4) # Insufficient gas | |
# Call the contract | |
msg(gascost, contract, value, argument) | |
# Return fee | |
send(msg.sender, fee + gascost) | |
# Clear the storage and advance the queue | |
contract.storage[tail] = 0 | |
contract.storage[1] += 1 | |
# Unlock the queue | |
contract.storage[0] = 0 | |
# END CRITICAL SECTION | |
return(0) | |
""" | |
second_contract_code = """ | |
code: | |
if msg.data[0] > 0: | |
contract.storage[0] = msg.data[0] | |
else: | |
return(contract.storage[0]) | |
""" | |
import serpent | |
from pyethereum import transactions, blocks, processblock, utils | |
#processblock.print_debug = 1 | |
key = utils.sha3('cow') | |
addr = utils.privtoaddr(key) | |
genesis = blocks.genesis({ addr: 10**18 }) | |
code = serpent.compile(contract_code) | |
tx1 = transactions.contract(0,10**12,10000,0,code).sign(key) | |
result, contract = processblock.apply_transaction(genesis,tx1) | |
print 'contract1', contract | |
#print genesis.to_dict() | |
code = serpent.compile(second_contract_code) | |
tx1 = transactions.contract(1,10**12,10000,0,code).sign(key) | |
result, contract2 = processblock.apply_transaction(genesis,tx1) | |
print 'contract2', contract2 | |
# Register a message in the message queue | |
tx2 = transactions.Transaction(2,10**12,10**5,contract,3000, | |
serpent.encode_datalist([1,contract2,10**12,300,200,80])).sign(key) | |
result, ans = processblock.apply_transaction(genesis,tx2) | |
print 'result:', serpent.decode_datalist(ans) | |
# Cause the message queue to pop | |
tx2 = transactions.Transaction(3,10**12,10**5,contract,3000, | |
serpent.encode_datalist([2])).sign(key) | |
result, ans = processblock.apply_transaction(genesis,tx2) | |
print 'result:', serpent.decode_datalist(ans) | |
# | |
tx2 = transactions.Transaction(4,10**12,10**5,contract2,3000, | |
serpent.encode_datalist([0])).sign(key) | |
result, ans = processblock.apply_transaction(genesis,tx2) | |
print 'Value after message is applied:', serpent.decode_datalist(ans) | |
#print genesis.to_dict() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment