// validate and queue transactions. func (self *TxPool) add(tx *types.Transaction) error { hash := tx.Hash() if self.pending[hash] != nil { return fmt.Errorf("Known transaction (%x)", hash[:4]) } err := self.validateTx(tx) if err != nil { return err } self.queueTx(hash, tx) if glog.V(logger.Debug) { var toname string if to := tx.To(); to != nil { toname = common.Bytes2Hex(to[:4]) } else { toname = "[NEW_CONTRACT]" } // we can ignore the error here because From is // verified in ValidateTransaction. f, _ := tx.From() from := common.Bytes2Hex(f[:4]) glog.Infof("(t) %x => %s (%v) %x\n", from, toname, tx.Value, hash) } return nil }
// newRPCPendingTransaction returns a pending transaction that will serialize to the RPC representation func newRPCPendingTransaction(tx *types.Transaction) *RPCTransaction { from, _ := tx.From() return &RPCTransaction{ From: from, Gas: rpc.NewHexNumber(tx.Gas()), GasPrice: rpc.NewHexNumber(tx.GasPrice()), Hash: tx.Hash(), Input: fmt.Sprintf("0x%x", tx.Data()), Nonce: rpc.NewHexNumber(tx.Nonce()), To: tx.To(), Value: rpc.NewHexNumber(tx.Value()), } }
func newTx(t *types.Transaction) *Tx { from, _ := t.From() return &Tx{ tx: t, To: t.To(), From: from, Value: rpc.NewHexNumber(t.Value()), Nonce: rpc.NewHexNumber(t.Nonce()), Data: "0x" + common.Bytes2Hex(t.Data()), GasLimit: rpc.NewHexNumber(t.Gas()), GasPrice: rpc.NewHexNumber(t.GasPrice()), Hash: t.Hash(), } }
// SendTransaction will create a transaction for the given transaction argument, sign it and submit it to the // transaction pool. func (s *PublicTransactionPoolAPI) SendTransaction(args SendTxArgs) (common.Hash, error) { if args.Gas == nil { args.Gas = rpc.NewHexNumber(defaultGas) } if args.GasPrice == nil { args.GasPrice = rpc.NewHexNumber(defaultGasPrice) } if args.Value == nil { args.Value = rpc.NewHexNumber(0) } s.txMu.Lock() defer s.txMu.Unlock() if args.Nonce == nil { args.Nonce = rpc.NewHexNumber(s.txPool.State().GetNonce(args.From)) } var tx *types.Transaction contractCreation := (args.To == common.Address{}) if contractCreation { tx = types.NewContractCreation(args.Nonce.Uint64(), args.Value.BigInt(), args.Gas.BigInt(), args.GasPrice.BigInt(), common.FromHex(args.Data)) } else { tx = types.NewTransaction(args.Nonce.Uint64(), args.To, args.Value.BigInt(), args.Gas.BigInt(), args.GasPrice.BigInt(), common.FromHex(args.Data)) } signedTx, err := s.sign(args.From, tx) if err != nil { return common.Hash{}, err } s.txPool.SetLocal(signedTx) if err := s.txPool.Add(signedTx); err != nil { return common.Hash{}, nil } if contractCreation { addr := crypto.CreateAddress(args.From, args.Nonce.Uint64()) glog.V(logger.Info).Infof("Tx(%s) created: %s\n", signedTx.Hash().Hex(), addr.Hex()) } else { glog.V(logger.Info).Infof("Tx(%s) to: %s\n", signedTx.Hash().Hex(), tx.To().Hex()) } return signedTx.Hash(), nil }
// SendRawTransaction will add the signed transaction to the transaction pool. // The sender is responsible for signing the transaction and using the correct nonce. func (s *PublicTransactionPoolAPI) SendRawTransaction(encodedTx string) (string, error) { tx := new(types.Transaction) if err := rlp.DecodeBytes(common.FromHex(encodedTx), tx); err != nil { return "", err } s.txPool.SetLocal(tx) if err := s.txPool.Add(tx); err != nil { return "", err } if tx.To() == nil { from, err := tx.From() if err != nil { return "", err } addr := crypto.CreateAddress(from, tx.Nonce()) glog.V(logger.Info).Infof("Tx(%x) created: %x\n", tx.Hash(), addr) } else { glog.V(logger.Info).Infof("Tx(%x) to: %x\n", tx.Hash(), tx.To()) } return tx.Hash().Hex(), nil }
// Transact forms a transaction from the given arguments and submits it to the // transactio pool for execution. func (be *registryAPIBackend) Transact(fromStr, toStr, nonceStr, valueStr, gasStr, gasPriceStr, codeStr string) (string, error) { if len(toStr) > 0 && toStr != "0x" && !common.IsHexAddress(toStr) { return "", errors.New("invalid address") } var ( from = common.HexToAddress(fromStr) to = common.HexToAddress(toStr) value = common.Big(valueStr) gas *big.Int price *big.Int data []byte contractCreation bool ) if len(gasStr) == 0 { gas = big.NewInt(90000) } else { gas = common.Big(gasStr) } if len(gasPriceStr) == 0 { price = big.NewInt(10000000000000) } else { price = common.Big(gasPriceStr) } data = common.FromHex(codeStr) if len(toStr) == 0 { contractCreation = true } nonce := be.txPool.State().GetNonce(from) if len(nonceStr) != 0 { nonce = common.Big(nonceStr).Uint64() } var tx *types.Transaction if contractCreation { tx = types.NewContractCreation(nonce, value, gas, price, data) } else { tx = types.NewTransaction(nonce, to, value, gas, price, data) } acc := accounts.Account{from} signature, err := be.am.Sign(acc, tx.SigHash().Bytes()) if err != nil { return "", err } signedTx, err := tx.WithSignature(signature) if err != nil { return "", err } be.txPool.SetLocal(signedTx) if err := be.txPool.Add(signedTx); err != nil { return "", nil } if contractCreation { addr := crypto.CreateAddress(from, nonce) glog.V(logger.Info).Infof("Tx(%s) created: %s\n", signedTx.Hash().Hex(), addr.Hex()) } else { glog.V(logger.Info).Infof("Tx(%s) to: %s\n", signedTx.Hash().Hex(), tx.To().Hex()) } return signedTx.Hash().Hex(), nil }