From 3e1ce94961200cc797f59740acc35013c8c0e78b Mon Sep 17 00:00:00 2001 From: Yuriy Glukhov Date: Mon, 5 Aug 2019 23:03:41 +0300 Subject: [PATCH] Moved Transaction encodings from nimbus --- eth/common/transaction.nim | 72 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 eth/common/transaction.nim diff --git a/eth/common/transaction.nim b/eth/common/transaction.nim new file mode 100644 index 0000000..63717e4 --- /dev/null +++ b/eth/common/transaction.nim @@ -0,0 +1,72 @@ +import + eth/[common, rlp, keys], nimcrypto + +proc initTransaction*(nonce: AccountNonce, gasPrice, gasLimit: GasInt, to: EthAddress, + value: UInt256, payload: Blob, V: byte, R, S: UInt256, isContractCreation = false): Transaction = + result.accountNonce = nonce + result.gasPrice = gasPrice + result.gasLimit = gasLimit + result.to = to + result.value = value + result.payload = payload + result.V = V + result.R = R + result.S = S + result.isContractCreation = isContractCreation + +type + TransHashObj = object + accountNonce: AccountNonce + gasPrice: GasInt + gasLimit: GasInt + to {.rlpCustomSerialization.}: EthAddress + value: UInt256 + payload: Blob + mIsContractCreation {.rlpIgnore.}: bool + +proc read(rlp: var Rlp, t: var TransHashObj, _: type EthAddress): EthAddress {.inline.} = + if rlp.blobLen != 0: + result = rlp.read(EthAddress) + else: + t.mIsContractCreation = true + +proc append(rlpWriter: var RlpWriter, t: TransHashObj, a: EthAddress) {.inline.} = + if t.mIsContractCreation: + rlpWriter.append("") + else: + rlpWriter.append(a) + +const + EIP155_CHAIN_ID_OFFSET = 35 + +func rlpEncode*(transaction: Transaction): auto = + # Encode transaction without signature + return rlp.encode(TransHashObj( + accountNonce: transaction.accountNonce, + gasPrice: transaction.gasPrice, + gasLimit: transaction.gasLimit, + to: transaction.to, + value: transaction.value, + payload: transaction.payload, + mIsContractCreation: transaction.isContractCreation + )) + +func rlpEncodeEIP155*(tx: Transaction): auto = + let V = (tx.V.int - EIP155_CHAIN_ID_OFFSET) div 2 + # Encode transaction without signature + return rlp.encode(Transaction( + accountNonce: tx.accountNonce, + gasPrice: tx.gasPrice, + gasLimit: tx.gasLimit, + to: tx.to, + value: tx.value, + payload: tx.payload, + isContractCreation: tx.isContractCreation, + V: V.byte, + R: 0.u256, + S: 0.u256 + )) + +func txHashNoSignature*(tx: Transaction): Hash256 = + # Hash transaction without signature + return keccak256.digest(if tx.V.int >= EIP155_CHAIN_ID_OFFSET: tx.rlpEncodeEIP155 else: tx.rlpEncode)