func makeTransactionForChainWithHoursFee(t *testing.T, bc *Blockchain, ux coin.UxOut, sec cipher.SecKey, hours, fee uint64) (coin.Transaction, cipher.SecKey) { chrs := ux.CoinHours(bc.Time()) if chrs < hours+fee { log.Panicf("CoinHours underflow. Have %d, need at least %d", chrs, hours+fee) } assert.Equal(t, cipher.AddressFromPubKey(cipher.PubKeyFromSecKey(sec)), ux.Body.Address) knownUx, exists := bc.GetUnspent().Get(ux.Hash()) assert.True(t, exists) assert.Equal(t, knownUx, ux) tx := coin.Transaction{} tx.PushInput(ux.Hash()) p, newSec := cipher.GenerateKeyPair() addr := cipher.AddressFromPubKey(p) tx.PushOutput(addr, 1e6, hours) coinsOut := ux.Body.Coins - 1e6 if coinsOut > 0 { tx.PushOutput(genAddress, coinsOut, chrs-hours-fee) } tx.SignInputs([]cipher.SecKey{sec}) assert.Equal(t, len(tx.Sigs), 1) assert.Nil(t, cipher.ChkSig(ux.Body.Address, cipher.AddSHA256(tx.HashInner(), tx.In[0]), tx.Sigs[0])) tx.UpdateHeader() assert.Nil(t, tx.Verify()) err := bc.VerifyTransaction(tx) assert.Nil(t, err) return tx, newSec }
func TransactionToJSON(tx coin.Transaction) string { var o TransactionJSON if err := tx.Verify(); err != nil { log.Panic("Input Transaction Invalid: Cannot serialize to JSON, fails verify") } o.Hash = tx.Hash().Hex() o.InnerHash = tx.InnerHash.Hex() if tx.InnerHash != tx.HashInner() { log.Panic("TransactionToJSON called with invalid transaction, inner hash mising") } o.Sigs = make([]string, len(tx.Sigs)) o.In = make([]string, len(tx.In)) o.Out = make([]TransactionOutputJSON, len(tx.Out)) for i, sig := range tx.Sigs { o.Sigs[i] = sig.Hex() } for i, x := range tx.In { o.In[i] = x.Hex() //hash to hex } for i, y := range tx.Out { o.Out[i] = NewTransactionOutputJSON(y, tx.InnerHash) } b, err := json.MarshalIndent(o, "", " ") if err != nil { log.Panic("Cannot serialize transaction as JSON") } return string(b) }