/// <summary> /// Applies an internally generated contract funds transfer message to the current state. /// </summary> public StateTransitionResult Apply(IState state, ContractTransferMessage message) { bool enoughBalance = EnsureSenderHasEnoughBalance(state, message.From, message.Amount); if (!enoughBalance) { return(StateTransitionResult.Fail((Gas)0, StateTransitionErrorKind.InsufficientBalance)); } var gasMeter = new GasMeter(message.GasLimit); // If it's not a contract, create a regular P2PKH tx // If it is a contract, do a regular contract call byte[] contractCode = state.ContractState.GetCode(message.To); if (contractCode == null || contractCode.Length == 0) { gasMeter.Spend((Gas)GasPriceList.TransferCost); // No contract at this address, create a regular P2PKH xfer state.AddInternalTransfer(new TransferInfo(message.From, message.To, message.Amount)); return(StateTransitionResult.Ok(gasMeter.GasConsumed, message.To)); } // For internal contract-contract transfers we need to add the value contained in the contract invocation transaction // to the internal transfer list. This must occur before we apply the message to the state. state.AddInternalTransfer(new TransferInfo(message.From, message.To, message.Amount)); gasMeter.Spend((Gas)GasPriceList.BaseCost); StateTransitionResult result = ApplyCall(state, message, contractCode, gasMeter); return(result); }
/// <summary> /// Applies an internally generated contract creation message to the current state. /// </summary> public StateTransitionResult Apply(IState state, InternalCreateMessage message) { bool enoughBalance = EnsureSenderHasEnoughBalance(state, message.From, message.Amount); if (!enoughBalance) { return(StateTransitionResult.Fail((Gas)0, StateTransitionErrorKind.InsufficientBalance)); // Trivial - just return and let the MethodCall gas account for it. } var gasMeter = new GasMeter(message.GasLimit); gasMeter.Spend((Gas)GasPriceList.CreateCost); byte[] contractCode = state.ContractState.GetCode(message.From); uint160 address = state.GenerateAddress(this.AddressGenerator); // For internal creates we need to add the value contained in the contract invocation transaction // to the internal transfer list. This must occur before we apply the message to the state. // For external creates we do not need to do this. state.AddInternalTransfer(new TransferInfo(message.From, address, message.Amount)); StateTransitionResult result = ApplyCreate(state, message.Parameters, contractCode, message, address, gasMeter, message.Type); return(result); }
/// <summary> /// Applies an internally generated contract creation message to the current state. /// </summary> public StateTransitionResult Apply(IState state, InternalCreateMessage message) { bool enoughBalance = this.EnsureSenderHasEnoughBalance(state, message.From, message.Amount); if (!enoughBalance) { return(StateTransitionResult.Fail((Gas)0, StateTransitionErrorKind.InsufficientBalance)); } byte[] contractCode = state.ContractState.GetCode(message.From); uint160 address = state.GenerateAddress(this.AddressGenerator); // For internal creates we need to add the value contained in the contract invocation transaction // to the internal transfer list. This must occur before we apply the message to the state. // For external creates we do not need to do this. state.AddInternalTransfer(new TransferInfo { From = message.From, To = address, Value = message.Amount }); StateTransitionResult result = this.ApplyCreate(state, message.Parameters, contractCode, message, address, message.Type); return(result); }
/// <summary> /// Applies an internally generated contract method call message to the current state. /// </summary> public StateTransitionResult Apply(IState state, InternalCallMessage message) { bool enoughBalance = EnsureSenderHasEnoughBalance(state, message.From, message.Amount); if (!enoughBalance) { return(StateTransitionResult.Fail((Gas)0, StateTransitionErrorKind.InsufficientBalance)); // Trivial - just return and let the MethodCall gas account for it. } var gasMeter = new GasMeter(message.GasLimit); gasMeter.Spend((Gas)GasPriceList.BaseCost); byte[] contractCode = state.ContractState.GetCode(message.To); if (contractCode == null || contractCode.Length == 0) { return(StateTransitionResult.Fail(gasMeter.GasConsumed, StateTransitionErrorKind.NoCode)); } // For internal calls we need to add the value contained in the contract invocation transaction // to the internal transfer list. This must occur before we apply the message to the state. // For external calls we do not need to do this. state.AddInternalTransfer(new TransferInfo(message.From, message.To, message.Amount)); StateTransitionResult result = ApplyCall(state, message, contractCode, gasMeter); return(result); }
/// <summary> /// Applies an internally generated contract method call message to the current state. /// </summary> public StateTransitionResult Apply(IState state, InternalCallMessage message) { bool enoughBalance = this.EnsureSenderHasEnoughBalance(state, message.From, message.Amount); if (!enoughBalance) { return(StateTransitionResult.Fail((Gas)0, StateTransitionErrorKind.InsufficientBalance)); } byte[] contractCode = state.ContractState.GetCode(message.To); if (contractCode == null || contractCode.Length == 0) { return(StateTransitionResult.Fail((Gas)0, StateTransitionErrorKind.NoCode)); } // For internal calls we need to add the value contained in the contract invocation transaction // to the internal transfer list. This must occur before we apply the message to the state. // For external calls we do not need to do this. state.AddInternalTransfer(new TransferInfo { From = message.From, To = message.To, Value = message.Amount }); StateTransitionResult result = this.ApplyCall(state, message, contractCode); return(result); }
/// <summary> /// Applies an internally generated contract creation message to the current state. /// </summary> public StateTransitionResult Apply(IState state, InternalCreateMessage message) { bool enoughBalance = this.EnsureContractHasEnoughBalance(state, message.From, message.Amount); if (!enoughBalance) { return(StateTransitionResult.Fail((Gas)0, StateTransitionErrorKind.InsufficientBalance)); } byte[] contractCode = state.ContractState.GetCode(message.From); StateTransitionResult result = this.ApplyCreate(state, message.Parameters, contractCode, message, message.Type); // For successful internal creates we need to add the transfer to the internal transfer list. // For external creates we do not need to do this. if (result.IsSuccess) { state.AddInternalTransfer(new TransferInfo { From = message.From, To = result.Success.ContractAddress, Value = message.Amount }); } return(result); }
/// <summary> /// Applies an internally generated contract method call message to the current state. /// </summary> public StateTransitionResult Apply(IState state, InternalCallMessage message) { bool enoughBalance = this.EnsureContractHasEnoughBalance(state, message.From, message.Amount); if (!enoughBalance) { return(StateTransitionResult.Fail((Gas)0, StateTransitionErrorKind.InsufficientBalance)); } byte[] contractCode = state.ContractState.GetCode(message.To); if (contractCode == null || contractCode.Length == 0) { return(StateTransitionResult.Fail((Gas)0, StateTransitionErrorKind.NoCode)); } StateTransitionResult result = this.ApplyCall(state, message, contractCode); // For successful internal calls we need to add the transfer to the internal transfer list. // For external calls we do not need to do this. if (result.IsSuccess) { state.AddInternalTransfer(new TransferInfo { From = message.From, To = message.To, Value = message.Amount }); } return(result); }
/// <summary> /// Applies an internally generated contract funds transfer message to the current state. /// </summary> public StateTransitionResult Apply(IState state, ContractTransferMessage message) { bool enoughBalance = this.EnsureContractHasEnoughBalance(state, message.From, message.Amount); if (!enoughBalance) { return(StateTransitionResult.Fail((Gas)0, StateTransitionErrorKind.InsufficientBalance)); } // If it's not a contract, create a regular P2PKH tx // If it is a contract, do a regular contract call byte[] contractCode = state.ContractState.GetCode(message.To); if (contractCode == null || contractCode.Length == 0) { // No contract at this address, create a regular P2PKH xfer state.AddInternalTransfer(new TransferInfo { From = message.From, To = message.To, Value = message.Amount }); return(StateTransitionResult.Ok((Gas)0, message.To)); } StateTransitionResult result = this.ApplyCall(state, message, contractCode); // For successful internal contract-contract transfers we need to add the transfer to the internal transfer list. if (result.IsSuccess) { state.AddInternalTransfer(new TransferInfo { From = message.From, To = message.To, Value = message.Amount }); } return(result); }
/// <summary> /// Applies an internally generated contract funds transfer message to the current state. /// </summary> public StateTransitionResult Apply(IState state, ContractTransferMessage message) { bool enoughBalance = this.EnsureSenderHasEnoughBalance(state, message.From, message.Amount); if (!enoughBalance) { return(StateTransitionResult.Fail((Gas)0, StateTransitionErrorKind.InsufficientBalance)); } // If it's not a contract, create a regular P2PKH tx // If it is a contract, do a regular contract call byte[] contractCode = state.ContractState.GetCode(message.To); if (contractCode == null || contractCode.Length == 0) { // No contract at this address, create a regular P2PKH xfer state.AddInternalTransfer(new TransferInfo { From = message.From, To = message.To, Value = message.Amount }); return(StateTransitionResult.Ok((Gas)0, message.To)); } // For internal contract-contract transfers we need to add the value contained in the contract invocation transaction // to the internal transfer list. This must occur before we apply the message to the state. state.AddInternalTransfer(new TransferInfo { From = message.From, To = message.To, Value = message.Amount }); StateTransitionResult result = this.ApplyCall(state, message, contractCode); return(result); }