Merge pull request #134 from status-im/createOpContractAddr

Add to Create Op, generateAddress
This commit is contained in:
coffeepots 2018-09-06 16:16:11 +01:00 committed by GitHub
commit 8c425dc173
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 21 additions and 9 deletions

View File

@ -135,6 +135,10 @@ proc getCode*(db: AccountStateDB, address: EthAddress): ByteRange =
let codeHash = db.getCodeHash(address)
result = db.trie.get(codeHash.toByteRange_Unnecessary)
proc hasCodeOrNonce*(account: AccountStateDB, address: EthAddress): bool {.inline.} =
account.getNonce(address) != 0 or account.getCodeHash(address) != EMPTY_SHA3
proc dumpAccount*(db: AccountStateDB, addressS: string): string =
let address = addressS.parseAddress
return fmt"{addressS}: Storage: {db.getStorage(address, 0.u256)}; getAccount: {db.getAccount address}"

View File

@ -0,0 +1,4 @@
import nimcrypto, eth_common, rlp
func generateAddress*(address: EthAddress, nonce: AccountNonce): EthAddress =
result[0..19] = keccak256.digest(rlp.encodeList(address, nonce).toOpenArray).data.toOpenArray(12, 31)

View File

@ -12,7 +12,7 @@ import
./gas_meter, ./gas_costs, ./opcode_values, ./vm_forks,
../memory, ../message, ../stack, ../code_stream, ../computation,
../../vm_state, ../../errors, ../../constants, ../../vm_types,
../../db/[db_chain, state_db]
../../db/[db_chain, state_db], ../../utils/addresses
# ##################################
# Syntactic sugar
@ -545,19 +545,23 @@ op create, inline = false, value, startPosition, size:
let callData = computation.memory.read(memPos, len)
## TODO dynamic gas that depends on remaining gas
var
contractAddress: EthAddress
isCollision: bool
##### getNonce type error: expression 'db' is of type: proc (vmState: untyped, readOnly: untyped, handler: untyped): untyped{.noSideEffect, gcsafe, locks: <unknown>.}
# computation.vmState.db(readOnly=true):
# let creationNonce = db.getNonce(computation.msg.storageAddress)
# db.incrementNonce(computation.msg.storageAddress)
let contractAddress = ZERO_ADDRESS # generateContractAddress(computation.msg.storageAddress, creationNonce)
let isCollision = false # TODO: db.accountHasCodeOrNonce ...
computation.vmState.mutateStateDB:
# Regarding collisions, see: https://github.com/status-im/nimbus/issues/133
# See: https://github.com/ethereum/EIPs/issues/684
let creationNonce = db.getNonce(computation.msg.storageAddress)
db.setNonce(computation.msg.storageAddress, creationNonce + 1)
contractAddress = generateAddress(computation.msg.storageAddress, creationNonce)
isCollision = db.hasCodeOrNonce(contractAddress)
if isCollision:
debug("Address collision while creating contract", address = contractAddress.toHex)
push: 0
return
raise newException(ValidationError, "Contract creation failed, address already in use")
let childMsg = prepareChildMessage(
computation,