2013-12-19 12:38:09 -06:00
|
|
|
from transactions import Transaction
|
|
|
|
from blocks import Block
|
2013-12-22 15:06:51 -06:00
|
|
|
import time
|
2013-12-26 15:17:18 -06:00
|
|
|
import sys
|
|
|
|
import rlp
|
2013-12-30 15:49:41 -06:00
|
|
|
import math
|
2013-12-19 12:38:09 -06:00
|
|
|
|
|
|
|
scriptcode_map = {
|
|
|
|
0x00: 'STOP',
|
2013-12-30 15:49:41 -06:00
|
|
|
0x01: 'ADD',
|
|
|
|
0x02: 'SUB',
|
|
|
|
0x03: 'MUL',
|
|
|
|
0x04: 'DIV',
|
|
|
|
0x05: 'SDIV',
|
|
|
|
0x06: 'MOD',
|
|
|
|
0x07: 'SMOD',
|
|
|
|
0x08: 'EXP',
|
|
|
|
0x09: 'NEG',
|
|
|
|
0x0a: 'LT',
|
|
|
|
0x0b: 'LE',
|
|
|
|
0x0c: 'GT',
|
|
|
|
0x0d: 'GE',
|
|
|
|
0x0e: 'EQ',
|
|
|
|
0x0f: 'NOT',
|
|
|
|
0x10: 'MYADDRESS',
|
|
|
|
0x11: 'TXSENDER',
|
|
|
|
0x12: 'TXVALUE',
|
|
|
|
0x13: 'TXFEE',
|
|
|
|
0x14: 'TXDATAN',
|
|
|
|
0x15: 'TXDATA',
|
|
|
|
0x16: 'BLK_PREVHASH',
|
|
|
|
0x17: 'BLK_COINBASE',
|
|
|
|
0x18: 'BLK_TIMESTAMP',
|
|
|
|
0x19: 'BLK_NUMBER',
|
|
|
|
0x1a: 'BLK_DIFFICULTY',
|
|
|
|
0x20: 'SHA256',
|
|
|
|
0x21: 'RIPEMD160',
|
|
|
|
0x22: 'ECMUL',
|
|
|
|
0x23: 'ECADD',
|
|
|
|
0x24: 'ECSIGN',
|
|
|
|
0x25: 'ECRECOVER',
|
|
|
|
0x26: 'ECVALID',
|
|
|
|
0x30: 'PUSH',
|
|
|
|
0x31: 'POP',
|
|
|
|
0x32: 'DUP',
|
|
|
|
0x33: 'DUPN',
|
|
|
|
0x34: 'SWAP',
|
|
|
|
0x35: 'SWAPN',
|
|
|
|
0x36: 'LOAD',
|
|
|
|
0x37: 'STORE',
|
|
|
|
0x40: 'JMP',
|
|
|
|
0x41: 'JMPI',
|
|
|
|
0x42: 'IND',
|
|
|
|
0x50: 'EXTRO',
|
|
|
|
0x51: 'BALANCE',
|
|
|
|
0x60: 'MKTX',
|
2013-12-22 15:06:51 -06:00
|
|
|
0xff: 'SUICIDE'
|
2013-12-19 12:38:09 -06:00
|
|
|
}
|
|
|
|
|
2013-12-22 15:06:51 -06:00
|
|
|
params = {
|
2014-01-07 11:40:49 -06:00
|
|
|
'stepfee': 1,
|
|
|
|
'txfee': 100,
|
|
|
|
'newcontractfee': 100,
|
|
|
|
'memoryfee': 20,
|
|
|
|
'datafee': 4,
|
|
|
|
'cryptofee': 10,
|
|
|
|
'extrofee': 10,
|
2013-12-22 15:06:51 -06:00
|
|
|
'blocktime': 60,
|
2014-01-07 11:40:49 -06:00
|
|
|
'period_1_reward': 10**18 * 800,
|
2013-12-22 15:06:51 -06:00
|
|
|
'period_1_duration': 57600,
|
2014-01-07 11:40:49 -06:00
|
|
|
'period_2_reward': 10**18 * 400,
|
2013-12-22 15:06:51 -06:00
|
|
|
'period_2_duration': 57600,
|
2014-01-07 11:40:49 -06:00
|
|
|
'period_3_reward': 10**18 * 100,
|
2013-12-22 15:06:51 -06:00
|
|
|
'period_3_duration': 57600,
|
2014-01-07 11:40:49 -06:00
|
|
|
'period_4_reward': 10**18 * 50
|
2013-12-19 12:38:09 -06:00
|
|
|
}
|
|
|
|
|
2014-01-07 11:40:49 -06:00
|
|
|
def getfee(block,t):
|
|
|
|
if t in ['stepfee','txfee','newcontractfee','memoryfee','datafee','cryptofee','extrofee']:
|
|
|
|
return int(10**24 / int(block.difficulty ** 0.5)) * params[t]
|
|
|
|
|
2013-12-26 15:17:18 -06:00
|
|
|
def process_transactions(block,transactions):
|
2013-12-22 15:06:51 -06:00
|
|
|
while len(transactions) > 0:
|
|
|
|
tx = transactions.pop(0)
|
2013-12-26 15:17:18 -06:00
|
|
|
enc = (tx.value, tx.fee, tx.sender.encode('hex'), tx.to.encode('hex'))
|
|
|
|
sys.stderr.write("Attempting to send %d plus fee %d from %s to %s\n" % enc)
|
|
|
|
# Grab data about sender, recipient and miner
|
|
|
|
sdata = rlp.decode(block.state.get(tx.sender)) or [0,0,0]
|
|
|
|
tdata = rlp.decode(block.state.get(tx.to)) or [0,0,0]
|
|
|
|
# Calculate fee
|
|
|
|
if tx.to == '\x00'*20:
|
2014-01-07 11:40:49 -06:00
|
|
|
fee = getfee('newcontractfee') + len(tx.data) * getfee('memoryfee')
|
2013-12-25 07:26:43 -06:00
|
|
|
else:
|
2014-01-07 11:40:49 -06:00
|
|
|
fee = getfee('txfee')
|
2013-12-22 15:06:51 -06:00
|
|
|
# Insufficient fee, do nothing
|
2013-12-26 15:17:18 -06:00
|
|
|
if fee > tx.fee:
|
|
|
|
sys.stderr.write("Insufficient fee\n")
|
|
|
|
continue
|
2013-12-22 15:06:51 -06:00
|
|
|
# Too much data, do nothing
|
2013-12-26 15:17:18 -06:00
|
|
|
if len(tx.data) > 256:
|
|
|
|
sys.stderr.write("Too many data items\n")
|
|
|
|
continue
|
|
|
|
if not sdata or sdata[1] < tx.value + tx.fee:
|
|
|
|
sys.stderr.write("Insufficient funds to send fee\n")
|
|
|
|
continue
|
|
|
|
elif tx.nonce != sdata[2] and sdata[0] == 0:
|
|
|
|
sys.stderr.write("Bad nonce\n")
|
|
|
|
continue
|
2013-12-22 15:06:51 -06:00
|
|
|
# Try to send the tx
|
2013-12-26 15:17:18 -06:00
|
|
|
if sdata[0] == 0: sdata[2] += 1
|
|
|
|
sdata[1] -= (tx.value + tx.fee)
|
|
|
|
block.reward += tx.fee
|
|
|
|
if tx.to != '':
|
|
|
|
tdata[1] += tx.value
|
|
|
|
else:
|
|
|
|
addr = tx.hash()[-20:]
|
|
|
|
adata = rlp.decode(block.state.get(addr))
|
|
|
|
if adata[2] != '':
|
|
|
|
sys.stderr.write("Contract already exists\n")
|
|
|
|
continue
|
|
|
|
block.state.update(addr,rlp.encode([1,tx.value,'']))
|
|
|
|
contract = block.get_contract(addr)
|
|
|
|
for i in range(len(tx.data)):
|
|
|
|
contract.update(encode(i,256,32),tx.data[i])
|
|
|
|
block.update_contract(addr)
|
|
|
|
print sdata, tdata
|
|
|
|
block.state.update(tx.sender,rlp.encode(sdata))
|
|
|
|
block.state.update(tx.to,rlp.encode(tdata))
|
2013-12-22 15:06:51 -06:00
|
|
|
# Evaluate contract if applicable
|
2013-12-26 15:17:18 -06:00
|
|
|
if tdata[0] == 1:
|
|
|
|
eval_contract(block,transactions,tx)
|
|
|
|
sys.stderr.write("tx processed\n")
|
|
|
|
|
|
|
|
def eval(block,transactions,timestamp,coinbase):
|
|
|
|
h = block.hash()
|
|
|
|
# Process all transactions
|
|
|
|
process_transactions(block,transactions)
|
2013-12-22 15:06:51 -06:00
|
|
|
# Pay miner fee
|
2013-12-26 15:17:18 -06:00
|
|
|
miner_state = rlp.decode(block.state.get(block.coinbase)) or [0,0,0]
|
2013-12-22 15:06:51 -06:00
|
|
|
block.number += 1
|
|
|
|
reward = 0
|
|
|
|
if block.number < params['period_1_duration']:
|
|
|
|
reward = params['period_1_reward']
|
|
|
|
elif block.number < params['period_2_duration']:
|
|
|
|
reward = params['period_2_reward']
|
|
|
|
elif block.number < params['period_3_duration']:
|
|
|
|
reward = params['period_3_reward']
|
2013-12-19 20:28:47 -06:00
|
|
|
else:
|
2013-12-22 15:06:51 -06:00
|
|
|
reward = params['period_4_reward']
|
2013-12-26 15:17:18 -06:00
|
|
|
miner_state[1] += reward + block.reward
|
2013-12-25 07:26:43 -06:00
|
|
|
for uncle in block.uncles:
|
2013-12-26 15:17:18 -06:00
|
|
|
sib_miner_state = rlp_decode(block.state.get(uncle[3]))
|
2014-01-07 11:40:49 -06:00
|
|
|
sib_miner_state[1] += reward*7/8
|
2013-12-26 15:17:18 -06:00
|
|
|
block.state.update(uncle[3],sib_miner_state)
|
|
|
|
miner_state[1] += reward/8
|
|
|
|
block.state.update(block.coinbase,rlp.encode(miner_state))
|
2013-12-22 15:06:51 -06:00
|
|
|
# Check timestamp
|
|
|
|
if timestamp < block.timestamp or timestamp > int(time.time()) + 3600:
|
2013-12-26 15:17:18 -06:00
|
|
|
raise Exception("timestamp not in valid range!")
|
2013-12-22 15:06:51 -06:00
|
|
|
# Update difficulty
|
|
|
|
if timestamp >= block.timestamp + 42:
|
|
|
|
block.difficulty += int(block.difficulty / 1024)
|
|
|
|
else:
|
|
|
|
block.difficulty -= int(block.difficulty / 1024)
|
|
|
|
block.prevhash = h
|
|
|
|
block.coinbase = coinbase
|
|
|
|
block.transactions = []
|
2013-12-25 07:26:43 -06:00
|
|
|
block.uncles = []
|
2013-12-22 15:06:51 -06:00
|
|
|
return block
|
2013-12-19 20:26:52 -06:00
|
|
|
|
2013-12-22 15:06:51 -06:00
|
|
|
def eval_contract(block,transaction_list,tx):
|
2013-12-26 15:17:18 -06:00
|
|
|
sys.stderr.write("evaluating contract\n")
|
2013-12-19 12:38:09 -06:00
|
|
|
address = tx.to
|
2013-12-30 15:49:41 -06:00
|
|
|
# Initialize stack
|
|
|
|
stack = []
|
2013-12-19 12:38:09 -06:00
|
|
|
index = 0
|
|
|
|
stepcounter = 0
|
2013-12-22 15:06:51 -06:00
|
|
|
contract = block.get_contract(address)
|
|
|
|
if not contract:
|
|
|
|
return
|
2013-12-19 12:38:09 -06:00
|
|
|
while 1:
|
2013-12-22 15:06:51 -06:00
|
|
|
# Convert the data item into a code piece
|
|
|
|
val_at_index = decode(contract.get(encode(index,256,32)),256)
|
|
|
|
code = [ int(val_at_index / (256**i)) % 256 for i in range(6) ]
|
2013-12-26 15:17:18 -06:00
|
|
|
code[0] = scriptcode_map.get(code[0],'INVALID')
|
|
|
|
sys.stderr.write("Evaluating: "+ str(code)+"\n")
|
2013-12-22 15:06:51 -06:00
|
|
|
# Invalid code instruction or STOP code stops execution sans fee
|
2013-12-30 15:49:41 -06:00
|
|
|
if val_at_index >= 256 or code[0] in ['STOP','INVALID']:
|
2013-12-26 15:17:18 -06:00
|
|
|
sys.stderr.write("stop code, exiting\n")
|
2013-12-22 15:06:51 -06:00
|
|
|
break
|
2013-12-19 12:38:09 -06:00
|
|
|
# Calculate fee
|
2013-12-22 15:06:51 -06:00
|
|
|
minerfee = 0
|
|
|
|
nullfee = 0
|
2013-12-19 12:38:09 -06:00
|
|
|
stepcounter += 1
|
|
|
|
if stepcounter > 16:
|
2014-01-07 11:40:49 -06:00
|
|
|
minerfee += getfee("stepfee")
|
2013-12-19 12:38:09 -06:00
|
|
|
c = scriptcode_map[code[0]]
|
2013-12-22 15:06:51 -06:00
|
|
|
if c in ['STORE','LOAD']:
|
2014-01-07 11:40:49 -06:00
|
|
|
minerfee += getfee("datafee")
|
2013-12-22 15:06:51 -06:00
|
|
|
if c in ['EXTRO','BALANCE']:
|
2014-01-07 11:40:49 -06:00
|
|
|
minerfee += getfee("extrofee")
|
2013-12-22 15:06:51 -06:00
|
|
|
if c in ['SHA256','RIPEMD-160','ECMUL','ECADD','ECSIGN','ECRECOVER']:
|
2014-01-07 11:40:49 -06:00
|
|
|
minerfee += getfee("cryptofee")
|
2013-12-19 12:38:09 -06:00
|
|
|
if c == 'STORE':
|
|
|
|
existing = block.get_contract_state(address,code[2])
|
2014-01-07 11:40:49 -06:00
|
|
|
if reg[code[1]] != 0: nullfee += getfee("memoryfee")
|
|
|
|
if existing: nullfee -= getfee("memoryfee")
|
2013-12-19 12:38:09 -06:00
|
|
|
|
2013-12-22 15:06:51 -06:00
|
|
|
# If we can't pay the fee, break, otherwise pay it
|
|
|
|
if block.get_balance(address) < minerfee + nullfee:
|
2013-12-26 15:17:18 -06:00
|
|
|
sys.stderr.write("insufficient fee, exiting\n")
|
2013-12-19 12:38:09 -06:00
|
|
|
break
|
2013-12-26 15:17:18 -06:00
|
|
|
block.set_balance(address,block.get_balance(address) - nullfee - minerfee)
|
|
|
|
block.reward += minerfee
|
|
|
|
sys.stderr.write("evaluating operation\n")
|
2013-12-30 15:49:41 -06:00
|
|
|
exit = False
|
|
|
|
def stack_pop(n):
|
|
|
|
if len(stack) < n:
|
|
|
|
sys.stderr.write("Stack height insufficient, exiting")
|
|
|
|
exit = True
|
|
|
|
return [0] * n
|
|
|
|
o = stack[-n:]
|
|
|
|
stack = stack[:-n]
|
|
|
|
return o
|
2013-12-22 15:06:51 -06:00
|
|
|
# Evaluate operations
|
|
|
|
if c == 'ADD':
|
2013-12-30 15:49:41 -06:00
|
|
|
x,y = stack_pop(2)
|
|
|
|
stack.append((x + y) % 2**256)
|
2013-12-19 12:38:09 -06:00
|
|
|
elif c == 'MUL':
|
2013-12-30 15:49:41 -06:00
|
|
|
x,y = stack_pop(2)
|
|
|
|
stack.append((x * y) % 2**256)
|
2013-12-19 12:38:09 -06:00
|
|
|
elif c == 'SUB':
|
2013-12-30 15:49:41 -06:00
|
|
|
x,y = stack_pop(2)
|
|
|
|
stack.append((x - y) % 2**256)
|
2013-12-19 12:38:09 -06:00
|
|
|
elif c == 'DIV':
|
2013-12-30 15:49:41 -06:00
|
|
|
x,y = stack_pop(2)
|
|
|
|
if y == 0: break
|
|
|
|
stack.append(int(x / y))
|
2013-12-19 12:38:09 -06:00
|
|
|
elif c == 'SDIV':
|
2013-12-30 15:49:41 -06:00
|
|
|
x,y = stack_pop(2)
|
|
|
|
if y == 0: break
|
|
|
|
sign = (1 if x < 2**255 else -1) * (1 if y < 2**255 else -1)
|
|
|
|
xx = x if x < 2**255 else 2**256 - x
|
|
|
|
yy = y if y < 2**255 else 2**256 - y
|
|
|
|
z = int(xx/yy)
|
|
|
|
stack.append(z if sign == 1 else 2**256 - z)
|
2013-12-19 12:38:09 -06:00
|
|
|
elif code == 'MOD':
|
2013-12-30 15:49:41 -06:00
|
|
|
x,y = stack_pop(2)
|
|
|
|
if y == 0: break
|
|
|
|
stack.append(x % y)
|
2013-12-19 12:38:09 -06:00
|
|
|
elif code == 'SMOD':
|
2013-12-30 15:49:41 -06:00
|
|
|
x,y = stack_pop(2)
|
|
|
|
if y == 0: break
|
|
|
|
sign = (1 if x < 2**255 else -1) * (1 if y < 2**255 else -1)
|
|
|
|
xx = x if x < 2**255 else 2**256 - x
|
|
|
|
yy = y if y < 2**255 else 2**256 - y
|
|
|
|
z = xx%yy
|
|
|
|
stack.append(z if sign == 1 else 2**256 - z)
|
2013-12-19 12:38:09 -06:00
|
|
|
elif code == 'EXP':
|
2013-12-30 15:49:41 -06:00
|
|
|
x,y = stack_pop(2)
|
|
|
|
stack.append(pow(x,y,2**256))
|
2013-12-19 12:38:09 -06:00
|
|
|
elif code == 'NEG':
|
2013-12-30 15:49:41 -06:00
|
|
|
stack.append(2**256 - stack.pop(1)[0])
|
2013-12-19 12:38:09 -06:00
|
|
|
elif code == 'LT':
|
2013-12-30 15:49:41 -06:00
|
|
|
x,y = stack_pop(2)
|
|
|
|
stack.append(1 if x < y else 0)
|
2013-12-19 12:38:09 -06:00
|
|
|
elif code == 'LE':
|
2013-12-30 15:49:41 -06:00
|
|
|
x,y = stack_pop(2)
|
|
|
|
stack.append(1 if x <= y else 0)
|
2013-12-19 12:38:09 -06:00
|
|
|
elif code == 'GT':
|
2013-12-30 15:49:41 -06:00
|
|
|
x,y = stack_pop(2)
|
|
|
|
stack.append(1 if x > y else 0)
|
2013-12-19 12:38:09 -06:00
|
|
|
elif code == 'GE':
|
2013-12-30 15:49:41 -06:00
|
|
|
x,y = stack_pop(2)
|
|
|
|
stack.append(1 if x >= y else 0)
|
2013-12-19 12:38:09 -06:00
|
|
|
elif code == 'EQ':
|
2013-12-30 15:49:41 -06:00
|
|
|
x,y = stack_pop(2)
|
|
|
|
stack.append(1 if x == y else 0)
|
2013-12-19 12:38:09 -06:00
|
|
|
elif code == 'NOT':
|
2013-12-30 15:49:41 -06:00
|
|
|
stack.append(1 if stack.pop(1)[0] == 0 else 0)
|
|
|
|
elif code == 'MYADDRESS':
|
|
|
|
stack.append(address)
|
|
|
|
elif code == 'TXSENDER':
|
|
|
|
stack.append(decode(tx.sender,256))
|
|
|
|
elif code == 'TXVALUE':
|
|
|
|
stack.append(tx.value)
|
|
|
|
elif code == 'TXFEE':
|
|
|
|
stack.append(tx.fee)
|
|
|
|
elif code == 'TXDATAN':
|
|
|
|
stack.append(len(tx.data))
|
|
|
|
elif code == 'TXDATA':
|
|
|
|
x, = stack_pop(1)
|
|
|
|
stack.append(0 if x >= len(tx.data) else tx.data[x])
|
|
|
|
elif code == 'BLK_PREVHASH':
|
|
|
|
stack.append(decode(block.prevhash,256))
|
|
|
|
elif code == 'BLK_COINBASE':
|
|
|
|
stack.append(decode(block.coinbase,160))
|
|
|
|
elif code == 'BLK_TIMESTAMP':
|
|
|
|
stack.append(block.timestamp)
|
|
|
|
elif code == 'BLK_NUMBER':
|
|
|
|
stack.append(block.number)
|
|
|
|
elif code == 'BLK_DIFFICULTY':
|
|
|
|
stack.append(block.difficulty)
|
2013-12-19 12:38:09 -06:00
|
|
|
elif code == 'SHA256':
|
2013-12-30 15:49:41 -06:00
|
|
|
L = stack_pop(1)
|
|
|
|
hdataitems = stack_pop(math.ceil(L / 32.0))
|
|
|
|
hdata = ''.join([encode(x,256,32) for x in hdataitems])[:L]
|
|
|
|
stack.append(decode(hashlib.sha256(hdata).digest(),256))
|
2013-12-19 12:38:09 -06:00
|
|
|
elif code == 'RIPEMD-160':
|
2013-12-30 15:49:41 -06:00
|
|
|
L = stack_pop(1)
|
|
|
|
hdataitems = stack_pop(math.ceil(L / 32.0))
|
|
|
|
hdata = ''.join([encode(x,256,32) for x in hdataitems])[:L]
|
|
|
|
stack.append(decode(hashlib.new('ripemd160',hdata).digest(),256))
|
2013-12-19 12:38:09 -06:00
|
|
|
elif code == 'ECMUL':
|
2013-12-30 15:49:41 -06:00
|
|
|
n,x,y = stack_pop(3)
|
2013-12-19 12:38:09 -06:00
|
|
|
# Point at infinity
|
2013-12-30 15:49:41 -06:00
|
|
|
if x == 0 and y == 0:
|
|
|
|
stack.extend([0,0])
|
2013-12-19 12:38:09 -06:00
|
|
|
# Point not on curve, coerce to infinity
|
2013-12-30 15:49:41 -06:00
|
|
|
elif x >= P or y >= P or (x ** 3 + 7 - y ** 2) % P != 0:
|
|
|
|
stack.extend([0,0])
|
2013-12-19 12:38:09 -06:00
|
|
|
# Legitimate point
|
|
|
|
else:
|
2013-12-30 15:49:41 -06:00
|
|
|
x2,y2 = base10_multiply((x,y),n)
|
|
|
|
stack.extend([x2,y2])
|
2013-12-19 12:38:09 -06:00
|
|
|
elif code == 'ECADD':
|
2013-12-30 15:49:41 -06:00
|
|
|
x1,y1,x2,y2 = stack_pop(4)
|
2013-12-22 15:06:51 -06:00
|
|
|
# Invalid point 1
|
2013-12-30 15:49:41 -06:00
|
|
|
if x1 >= P or y1 >= P or (x1 ** 3 + 7 - y1 ** 2) % P != 0:
|
|
|
|
stack.extend([0,0])
|
2013-12-22 15:06:51 -06:00
|
|
|
# Invalid point 2
|
2013-12-30 15:49:41 -06:00
|
|
|
elif x2 >= P or y2 >= P or (x2 ** 3 + 7 - y2 ** 2) % P != 0:
|
|
|
|
stack.extend([0,0])
|
2013-12-22 15:06:51 -06:00
|
|
|
# Legitimate points
|
2013-12-19 12:38:09 -06:00
|
|
|
else:
|
2013-12-30 15:49:41 -06:00
|
|
|
x3,y3 = base10_add((x1,y1),(x2,y2))
|
|
|
|
stack.extend([x3,y3])
|
2013-12-22 15:06:51 -06:00
|
|
|
elif code == 'ECSIGN':
|
2013-12-30 15:49:41 -06:00
|
|
|
k,h = stack_pop(2)
|
|
|
|
v,r,s = ecdsa_raw_sign(h,k)
|
|
|
|
stack.extend([v,r,s])
|
2013-12-22 15:06:51 -06:00
|
|
|
elif code == 'ECRECOVER':
|
2013-12-30 15:49:41 -06:00
|
|
|
h,v,r,s = stack_pop(4)
|
|
|
|
x,y = ecdsa_raw_recover((v,r,s),h)
|
|
|
|
stack.extend([x,y])
|
|
|
|
elif code == 'PUSH':
|
|
|
|
stack.append(contract.get(encode(index + 1,256,32)))
|
|
|
|
index += 1
|
|
|
|
elif code == 'POP':
|
|
|
|
stack_pop(1)
|
|
|
|
elif code == 'DUP':
|
|
|
|
x, = stack_pop(1)
|
|
|
|
stack.extend([x,x])
|
|
|
|
elif code == 'DUPN':
|
|
|
|
arr = stack_pop(contract.get(encode(index + 1,256,32)))
|
|
|
|
arr.append(arr[0])
|
|
|
|
stack.extend(arr)
|
|
|
|
index += 1
|
|
|
|
elif code == 'SWAP':
|
|
|
|
x,y = stack_pop(2)
|
|
|
|
stack.extend([y,x])
|
2014-01-07 11:40:49 -06:00
|
|
|
elif code == 'SWAPN':
|
2013-12-30 15:49:41 -06:00
|
|
|
arr = stack_pop(contract.get(encode(index + 1,256,32)))
|
|
|
|
arr.append(arr[0])
|
|
|
|
arr.pop(0)
|
|
|
|
stack.extend(arr)
|
|
|
|
index += 1
|
2013-12-22 15:06:51 -06:00
|
|
|
elif code == 'LOAD':
|
2013-12-30 15:49:41 -06:00
|
|
|
stack.append(contract.get(encode(stack_pop(1)[0],256,32)))
|
|
|
|
elif code == 'STORE':
|
|
|
|
x,y = stack_pop(2)
|
|
|
|
if exit: break
|
|
|
|
contract.update(encode(x,256,32),y)
|
2013-12-19 12:38:09 -06:00
|
|
|
elif code == 'JMP':
|
2013-12-30 15:49:41 -06:00
|
|
|
index = stack_pop(1)[0]
|
2013-12-19 20:26:52 -06:00
|
|
|
elif code == 'JMPI':
|
2013-12-30 15:49:41 -06:00
|
|
|
newpos,c = stack_pop(2)
|
|
|
|
if c != 0: index = newpos
|
2013-12-19 12:38:09 -06:00
|
|
|
elif code == 'IND':
|
2013-12-30 15:49:41 -06:00
|
|
|
stack.append(index)
|
2013-12-19 12:38:09 -06:00
|
|
|
elif code == 'EXTRO':
|
2013-12-30 15:49:41 -06:00
|
|
|
ind,addr = stack_pop(2)
|
|
|
|
stack.push(block.get_contract(encode(addr,256,20)).get(encode(ind,256,32)))
|
2013-12-19 12:38:09 -06:00
|
|
|
elif code == 'BALANCE':
|
2013-12-30 15:49:41 -06:00
|
|
|
stack.push(block.get_balance(encode(stack_pop(1)[0],256,20)))
|
2013-12-19 12:38:09 -06:00
|
|
|
elif code == 'MKTX':
|
2013-12-30 15:49:41 -06:00
|
|
|
datan,fee,value,to = stack_pop(4)
|
|
|
|
if exit:
|
|
|
|
break
|
|
|
|
elif (value + fee) > block.get_balance(address):
|
|
|
|
break
|
2013-12-19 20:26:52 -06:00
|
|
|
else:
|
2013-12-30 15:49:41 -06:00
|
|
|
data = stack_pop(datan)
|
|
|
|
tx = Transaction(0,encode(to,256,20),value,fee,data)
|
2013-12-26 15:17:18 -06:00
|
|
|
tx.sender = address
|
2013-12-22 15:06:51 -06:00
|
|
|
transaction_list.insert(0,tx)
|
2013-12-19 12:38:09 -06:00
|
|
|
elif code == 'SUICIDE':
|
2013-12-22 15:06:51 -06:00
|
|
|
sz = contract.get_size()
|
2014-01-07 11:40:49 -06:00
|
|
|
negfee = -sz * getfee("memoryfee")
|
2013-12-30 15:49:41 -06:00
|
|
|
toaddress = encode(stack_pop(1)[0],256,20)
|
|
|
|
block.pay_fee(toaddress,negfee,False)
|
2013-12-22 15:06:51 -06:00
|
|
|
contract.root = ''
|
2013-12-19 20:26:52 -06:00
|
|
|
break
|
2013-12-30 15:49:41 -06:00
|
|
|
if exit: break
|
2013-12-22 15:06:51 -06:00
|
|
|
block.update_contract(address,contract)
|