def casper_setup_block(chain, state=None, timestamp=None, coinbase='\x35' * 20, extra_data='moo ha ha says the laughing cow.'): state = state or chain.state blk = Block(BlockHeader()) now = timestamp or chain.time() prev_blknumber = call_casper(state, 'getBlockNumber') blk.header.number = prev_blknumber + 1 blk.header.difficulty = 1 blk.header.gas_limit = call_casper(state, 'getGasLimit') blk.header.timestamp = max(now, state.prev_headers[0].timestamp + 1) blk.header.prevhash = apply_const_message( state, sender=casper_config['METROPOLIS_ENTRY_POINT'], to=casper_config['METROPOLIS_BLOCKHASH_STORE'], data=utils.encode_int32(prev_blknumber)) blk.header.coinbase = coinbase blk.header.extra_data = extra_data blk.header.bloom = 0 blk.uncles = [] initialize(state, blk) for tx in get_dunkle_candidates(chain, state): assert apply_transaction(state, tx) blk.transactions.append(tx) log_bc.info('Block set up with number %d and prevhash %s, %d dunkles' % (blk.header.number, utils.encode_hex( blk.header.prevhash), len(blk.transactions))) return blk
def casper_validate_header(state, header): output = apply_const_message(state, sender=state.config['SYSTEM_ENTRY_POINT'], to=state.config['SERENITY_HEADER_VERIFIER'], data=rlp.encode(header)) if output is None: raise ValueError("Validation call failed with exception") elif output: raise ValueError(output)
def get_dao_balance(state, address): msg_data = CallData( [ord(x) for x in dao_ct.encode('balanceOf', [address])]) msg = Message(normalize_address(address), normalize_address(dao), 0, 1000000, msg_data, code_address=normalize_address(dao)) output = ''.join(map(chr, apply_const_message(state, msg))) return dao_ct.decode('balanceOf', output)[0]
def call_casper(state, fun, args=[], gas=1000000, value=0): ct = get_casper_ct() abidata = vm.CallData([utils.safe_ord(x) for x in ct.encode(fun, args)]) msg = vm.Message(casper_config['METROPOLIS_ENTRY_POINT'], casper_config['CASPER_ADDR'], value, gas, abidata) o = apply_const_message(state, msg) if o: # print 'cc', fun, args, ct.decode(fun, o)[0] return ct.decode(fun, o)[0] else: return None
def generate_genesis(path=None, num_participants=1): privkeys = [ utils.sha3(utils.to_string(i)) for i in range(num_participants) ] addrs = [utils.privtoaddr(k) for k in privkeys] deposit_sizes = [i * 500 + 500 for i in range(num_participants)] randaos = [RandaoManager(utils.sha3(k)) for k in privkeys] validators = [(generate_validation_code(a), ds * 10**18, r.get(9999), a) for a, ds, r in zip(addrs, deposit_sizes, randaos)] s = make_casper_genesis(validators=validators, alloc={a: { 'balance': 10**18 } for a in addrs}, timestamp=int(time.time()), epoch_length=100) genesis_hash = apply_const_message( s, sender=casper_config['METROPOLIS_ENTRY_POINT'], to=casper_config['METROPOLIS_BLOCKHASH_STORE'], data=utils.encode_int32(0)) genesis_number = call_casper(s, 'getBlockNumber') print('genesis block hash: %s' % utils.encode_hex(genesis_hash)) print('genesis block number: %d' % genesis_number) print('%d validators: %r' % (num_participants, [utils.encode_hex(a) for a in addrs])) snapshot = s.to_snapshot() header = s.prev_headers[0] genesis = { "nonce": "0x" + utils.encode_hex(header.nonce), "difficulty": utils.int_to_hex(header.difficulty), "mixhash": "0x" + utils.encode_hex(header.mixhash), "coinbase": "0x" + utils.encode_hex(header.coinbase), "timestamp": utils.int_to_hex(header.timestamp), "parentHash": "0x" + utils.encode_hex(header.prevhash), "extraData": "0x" + utils.encode_hex(header.extra_data), "gasLimit": utils.int_to_hex(header.gas_limit), "alloc": snapshot["alloc"] } if path: with open(path, 'w') as f: json.dump(genesis, f, sort_keys=False, indent=4, separators=(',', ': ')) print('casper genesis generated') else: return genesis
dao_ct.encode('approve', [withdrawer, 100000 * 10**18])).sign('\x33' * 32) tx1._sender = normalize_address(my_account) apply_transaction(state, tx1) # Check allowance allowance = dao_ct.decode( 'allowance', ''.join( map( chr, apply_const_message( state, Message(normalize_address(my_account), normalize_address(dao), 0, 1000000, CallData([ ord(x) for x in dao_ct.encode( 'allowance', [my_account, withdrawer]) ]), code_address=dao)))))[0] assert allowance == 100000 * 10**18, allowance print 'Allowance verified' # Claim the ETH tx2 = Transaction(state.get_nonce(my_account), 0, 1000000, withdrawer, 0, withdrawer_ct.encode('withdraw', [])).sign('\x33' * 32) tx2._sender = normalize_address(my_account) apply_transaction(state, tx2)
def get_dao_balance(state, address): msg_data = CallData([ord(x) for x in dao_ct.encode('balanceOf', [address])]) msg = Message(normalize_address(address), normalize_address(dao), 0, 1000000, msg_data, code_address=normalize_address(dao)) output = ''.join(map(chr, apply_const_message(state, msg))) return dao_ct.decode('balanceOf', output)[0]
assert med_balance == pre_balance assert med_dao_tokens == pre_dao_tokens assert med_withdrawer_balance == pre_withdrawer_balance > 0 print 'ETH claim without approving failed, as expected' # Approve the withdrawal tx1 = Transaction(state.get_nonce(my_account), 0, 1000000, dao, 0, dao_ct.encode('approve', [withdrawer, 100000 * 10**18])).sign('\x33' * 32) tx1._sender = normalize_address(my_account) apply_transaction(state, tx1) # Check allowance allowance = dao_ct.decode('allowance', ''.join(map(chr, apply_const_message(state, Message(normalize_address(my_account), normalize_address(dao), 0, 1000000, CallData([ord(x) for x in dao_ct.encode('allowance', [my_account, withdrawer])]), code_address=dao)))))[0] assert allowance == 100000 * 10**18, allowance print 'Allowance verified' # Claim the ETH tx2 = Transaction(state.get_nonce(my_account), 0, 1000000, withdrawer, 0, withdrawer_ct.encode('withdraw', [])).sign('\x33' * 32) tx2._sender = normalize_address(my_account) apply_transaction(state, tx2) # Compare post_balance post_balance = state.get_balance(my_account) post_dao_tokens = get_dao_balance(state, my_account) print 'Post ETH (wei) balance: %d' % post_balance