//InjectTransaction makes the blockchain server aware of raw transactions //InjectTransaction inserts the transaction into the unconfirmed set // TODO: lock for thread safety func (self *Blockchain) InjectTransaction(txn coin.Transaction) error { //strict filter would disallow transactions that cant be executed from unspent output set if txn.Size() > MaxTransactionSize { //16 KB/max size return errors.New("transaction over size limit") } if err := self.blockchain.VerifyTransaction(txn); err != nil { return err } self.Unconfirmed.RecordTxn(txn) return nil }
// Performs additional transaction verification at the unconfirmed pool level. // This checks tunable parameters that should prevent the transaction from // entering the blockchain, but cannot be done at the blockchain level because // they may be changed. func VerifyTransaction(bc *coin.Blockchain, t *coin.Transaction, maxSize int, burnFactor uint64) error { if t.Size() > maxSize { return errors.New("Transaction too large") } if fee, err := bc.TransactionFee(t); err != nil { return err } else if burnFactor != 0 && t.OutputHours()/burnFactor > fee { return errors.New("Transaction fee minimum not met") } return nil }
func TransactionFromJSON(str string) (coin.Transaction, error) { var TxIn TransactionJSON err := json.Unmarshal([]byte(str), TxIn) if err != nil { errors.New("cannot deserialize") } var tx coin.Transaction tx.Sigs = make([]cipher.Sig, len(TxIn.Sigs)) tx.In = make([]cipher.SHA256, len(TxIn.In)) tx.Out = make([]coin.TransactionOutput, len(TxIn.Out)) for i, _ := range tx.Sigs { sig2, err := cipher.SigFromHex(TxIn.Sigs[i]) if err != nil { return coin.Transaction{}, errors.New("invalid signature") } tx.Sigs[i] = sig2 } for i, _ := range tx.In { hash, err := cipher.SHA256FromHex(TxIn.In[i]) if err != nil { return coin.Transaction{}, errors.New("invalid signature") } tx.In[i] = hash } for i, _ := range tx.Out { out, err := TransactionOutputFromJSON(TxIn.Out[i]) if err != nil { return coin.Transaction{}, errors.New("invalid output") } tx.Out[i] = out } tx.Length = uint32(tx.Size()) tx.Type = 0 hash, err := cipher.SHA256FromHex(TxIn.Hash) if err != nil { return coin.Transaction{}, errors.New("invalid hash") } if hash != tx.Hash() { } InnerHash, err := cipher.SHA256FromHex(TxIn.Hash) if InnerHash != tx.InnerHash { return coin.Transaction{}, errors.New("inner hash") } err = tx.Verify() if err != nil { return coin.Transaction{}, errors.New("transaction failed verification") } return tx, nil }