protected void SerializePrefix(byte[] bytes, ContractTxData contractTxData) { byte[] vmVersion = this.primitiveSerializer.Serialize(contractTxData.VmVersion); byte[] gasPrice = this.primitiveSerializer.Serialize(contractTxData.GasPrice); byte[] gasLimit = this.primitiveSerializer.Serialize(contractTxData.GasLimit.Value); bytes[0] = contractTxData.OpCodeType; vmVersion.CopyTo(bytes, OpcodeSize); gasPrice.CopyTo(bytes, OpcodeSize + VmVersionSize); gasLimit.CopyTo(bytes, OpcodeSize + VmVersionSize + GasPriceSize); }
private Result <ContractTxData> SerializeCreateContract(byte[] smartContractBytes, int vmVersion, ulong gasPrice, Gas gasLimit) { var remaining = smartContractBytes.Slice(PrefixSize, (uint)(smartContractBytes.Length - PrefixSize)); IList <byte[]> decodedParams = RLPDecode(remaining); var contractExecutionCode = this.primitiveSerializer.Deserialize <byte[]>(decodedParams[0]); var methodParameters = this.DeserializeMethodParameters(decodedParams[1]); var callData = new ContractTxData(vmVersion, gasPrice, gasLimit, contractExecutionCode, methodParameters); return(Result.Ok(callData)); }
protected virtual Result <ContractTxData> SerializeCreateContract(byte[] smartContractBytes, int vmVersion, ulong gasPrice, RuntimeObserver.Gas gasLimit) { byte[] remaining = smartContractBytes.Slice(PrefixSize, (uint)(smartContractBytes.Length - PrefixSize)); IList <byte[]> decodedParams = RLPDecode(remaining); var contractExecutionCode = this.primitiveSerializer.Deserialize <byte[]>(decodedParams[0]); object[] methodParameters = this.DeserializeMethodParameters(decodedParams[1]); string[] signatures = (decodedParams.Count > 2) ? this.DeserializeSignatures(decodedParams[2]) : null; var callData = new ContractTxData(vmVersion, gasPrice, gasLimit, contractExecutionCode, methodParameters, signatures); return(Result.Ok(callData)); }
private Result <ContractTxData> SerializeCallContract(byte[] smartContractBytes, int vmVersion, ulong gasPrice, Gas gasLimit) { var contractAddressBytes = smartContractBytes.Slice(PrefixSize, AddressSize); var contractAddress = new uint160(contractAddressBytes); var remaining = smartContractBytes.Slice(CallContractPrefixSize, (uint)(smartContractBytes.Length - CallContractPrefixSize)); IList <byte[]> decodedParams = RLPDecode(remaining); var methodName = this.primitiveSerializer.Deserialize <string>(decodedParams[0]); var methodParameters = this.DeserializeMethodParameters(decodedParams[1]); var callData = new ContractTxData(vmVersion, gasPrice, gasLimit, contractAddress, methodName, methodParameters); return(Result.Ok(callData)); }
private byte[] SerializeCreateContract(ContractTxData contractTxData) { var rlpBytes = new List <byte[]>(); rlpBytes.Add(contractTxData.ContractExecutionCode); this.AddMethodParams(rlpBytes, contractTxData.MethodParameters); var encoded = RLP.EncodeList(rlpBytes.Select(RLP.EncodeElement).ToArray()); var bytes = new byte[PrefixSize + encoded.Length]; this.SerializePrefix(bytes, contractTxData); encoded.CopyTo(bytes, PrefixSize); return(bytes); }
public Result <ContractTxData> SerializeCallContract(byte[] smartContractBytes, int vmVersion, ulong gasPrice, RuntimeObserver.Gas gasLimit) { byte[] contractAddressBytes = smartContractBytes.Slice(PrefixSize, AddressSize); var contractAddress = new uint160(contractAddressBytes); byte[] remaining = smartContractBytes.Slice(CallContractPrefixSize, (uint)(smartContractBytes.Length - CallContractPrefixSize)); IList <byte[]> decodedParams = RLPDecode(remaining); string methodName = this.primitiveSerializer.Deserialize <string>(decodedParams[0]); object[] methodParameters = this.DeserializeMethodParameters(decodedParams[1]); string[] signatures = (decodedParams.Count > 2) ? this.DeserializeSignatures(decodedParams[2]) : null; var callData = new ContractTxData(vmVersion, gasPrice, gasLimit, contractAddress, methodName, methodParameters, signatures); return(Result.Ok(callData)); }
private byte[] SerializeCallContract(ContractTxData contractTxData) { var rlpBytes = new List <byte[]>(); rlpBytes.Add(this.primitiveSerializer.Serialize(contractTxData.MethodName)); this.AddMethodParams(rlpBytes, contractTxData.MethodParameters); var encoded = RLP.EncodeList(rlpBytes.Select(RLP.EncodeElement).ToArray()); var bytes = new byte[CallContractPrefixSize + encoded.Length]; this.SerializePrefix(bytes, contractTxData); contractTxData.ContractAddress.ToBytes().CopyTo(bytes, PrefixSize); encoded.CopyTo(bytes, CallContractPrefixSize); return(bytes); }
public byte[] Serialize(ContractTxData contractTxData) { return(IsCallContract(contractTxData.OpCodeType) ? this.SerializeCallContract(contractTxData) : this.SerializeCreateContract(contractTxData)); }
public IContractExecutionResult Execute(IContractTransactionContext transactionContext) { // Deserialization can't fail because this has already been through SmartContractFormatRule. Result <ContractTxData> callDataDeserializationResult = this.serializer.Deserialize(transactionContext.Data); ContractTxData callData = callDataDeserializationResult.Value; bool creation = callData.IsCreateContract; var block = new Block( transactionContext.BlockHeight, transactionContext.CoinbaseAddress.ToAddress() ); IState state = this.stateFactory.Create( this.stateRoot, block, transactionContext.TxOutValue, transactionContext.TransactionHash); StateTransitionResult result; IState newState = state.Snapshot(); if (creation) { var message = new ExternalCreateMessage( transactionContext.Sender, transactionContext.TxOutValue, callData.GasLimit, callData.ContractExecutionCode, callData.MethodParameters ); result = this.stateProcessor.Apply(newState, message); } else { var message = new ExternalCallMessage( callData.ContractAddress, transactionContext.Sender, transactionContext.TxOutValue, callData.GasLimit, new MethodCall(callData.MethodName, callData.MethodParameters) ); result = this.stateProcessor.Apply(newState, message); } bool revert = !result.IsSuccess; Transaction internalTransaction = this.transferProcessor.Process( newState.ContractState, result.Success?.ContractAddress, transactionContext, newState.InternalTransfers, revert); if (result.IsSuccess) { state.TransitionTo(newState); } bool outOfGas = result.IsFailure && result.Error.Kind == StateTransitionErrorKind.OutOfGas; (Money fee, TxOut refundTxOut) = this.refundProcessor.Process( callData, transactionContext.MempoolFee, transactionContext.Sender, result.GasConsumed, outOfGas); var executionResult = new SmartContractExecutionResult { To = !callData.IsCreateContract ? callData.ContractAddress : null, NewContractAddress = !revert && creation ? result.Success?.ContractAddress : null, ErrorMessage = result.Error?.GetErrorMessage(), Revert = revert, GasConsumed = result.GasConsumed, Return = result.Success?.ExecutionResult, InternalTransaction = internalTransaction, Fee = fee, Refund = refundTxOut, Logs = state.GetLogs(this.contractPrimitiveSerializer) }; return(executionResult); }