本文整理汇总了Golang中github.com/skycoin/skycoin/src/coin.Transaction.PushInput方法的典型用法代码示例。如果您正苦于以下问题:Golang Transaction.PushInput方法的具体用法?Golang Transaction.PushInput怎么用?Golang Transaction.PushInput使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类github.com/skycoin/skycoin/src/coin.Transaction
的用法示例。
在下文中一共展示了Transaction.PushInput方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。
示例1: InitTransaction
func InitTransaction() coin.Transaction {
var tx coin.Transaction
output := cipher.MustSHA256FromHex("043836eb6f29aaeb8b9bfce847e07c159c72b25ae17d291f32125e7f1912e2a0")
tx.PushInput(output)
for i := 0; i < 100; i++ {
addr := cipher.MustDecodeBase58Address(AddrList[i])
tx.PushOutput(addr, 1e12, 1) // 10e6*10e6
}
/*
seckeys := make([]cipher.SecKey, 1)
seckey := ""
seckeys[0] = cipher.MustSecKeyFromHex(seckey)
tx.SignInputs(seckeys)
*/
txs := make([]cipher.Sig, 1)
sig := "ed9bd7a31fe30b9e2d53b35154233dfdf48aaaceb694a07142f84cdf4f5263d21b723f631817ae1c1f735bea13f0ff2a816e24a53ccb92afae685fdfc06724de01"
txs[0] = cipher.MustSigFromHex(sig)
tx.Sigs = txs
tx.UpdateHeader()
err := tx.Verify()
if err != nil {
log.Panic(err)
}
log.Printf("signature= %s", tx.Sigs[0].Hex())
return tx
}
示例2: TestBlockchainVerifyBlock
func TestBlockchainVerifyBlock(t *testing.T) {
ft := FakeTree{}
bc := NewBlockchain(&ft, nil)
gb := bc.CreateGenesisBlock(genAddress, _genCoins, _genTime)
// Genesis block not valid after the fact
assert.NotNil(t, bc.verifyBlock(gb))
assert.Equal(t, bc.Len(), uint64(1))
_, ux := addBlockToBlockchain(t, bc)
assert.Equal(t, bc.Len(), uint64(3))
// Valid block
tx := coin.Transaction{}
tx.PushInput(ux.Hash())
tx.PushOutput(genAddress, ux.Body.Coins, ux.CoinHours(bc.Time()))
tx.SignInputs([]cipher.SecKey{genSecret})
tx.UpdateHeader()
b, err := bc.NewBlockFromTransactions(coin.Transactions{tx}, bc.Time()+_incTime)
assert.Equal(t, len(b.Body.Transactions), 1)
assert.Equal(t, len(b.Body.Transactions[0].Out), 1)
assert.Nil(t, err)
assert.Nil(t, bc.verifyBlock(b))
// Invalid block header
b.Head.BkSeq = gb.Head.BkSeq
assert.Equal(t, len(b.Body.Transactions), 1)
assert.Equal(t, len(b.Body.Transactions[0].Out), 1)
assertError(t, bc.verifyBlock(b), "BkSeq invalid")
// Invalid transactions, makes duplicate outputs
b.Head.BkSeq = bc.Head().Head.BkSeq + 1
b.Body.Transactions = append(b.Body.Transactions, b.Body.Transactions[0])
b.Head.BodyHash = b.HashBody()
assertError(t, bc.verifyBlock(b),
"Duplicate unspent output across transactions")
}
示例3: TestCreateUnspents
func TestCreateUnspents(t *testing.T) {
ft := FakeTree{}
bc := NewBlockchain(&ft, nil)
bc.CreateGenesisBlock(genAddress, _genCoins, _genTime)
// 1 out
tx := coin.Transaction{}
tx.PushOutput(genAddress, 11e6, 255)
bh := coin.BlockHeader{
Time: tNow(),
BkSeq: uint64(1),
}
uxout := coin.CreateUnspents(bh, tx)
assert.Equal(t, len(uxout), 1)
assertValidUnspents(t, bh, tx, uxout)
// Multiple outs. Should work regardless of validity
tx = coin.Transaction{}
ux := makeUxOut(t)
tx.PushInput(ux.Hash())
tx.PushOutput(genAddress, 100, 150)
tx.PushOutput(genAddress, 200, 77)
bh.BkSeq++
uxout = coin.CreateUnspents(bh, tx)
assert.Equal(t, len(uxout), 2)
assertValidUnspents(t, bh, tx, uxout)
// No outs
tx = coin.Transaction{}
uxout = coin.CreateUnspents(bh, tx)
assertValidUnspents(t, bh, tx, uxout)
}
示例4: splitUnspent
func splitUnspent(t *testing.T, bc *Blockchain, ux coin.UxOut) coin.UxArray {
tx := coin.Transaction{}
hrs := ux.CoinHours(bc.Time())
if hrs < 2 {
log.Panic("Not enough hours, would generate duplicate output")
}
assert.Equal(t, ux.Body.Address, genAddress)
tx.PushInput(ux.Hash())
coinsA := ux.Body.Coins / 2
coinsB := coinsA
if (ux.Body.Coins/1e6)%2 == 1 {
coinsA = (ux.Body.Coins - 1e6) / 2
coinsB = coinsA + 1e6
}
tx.PushOutput(genAddress, coinsA, hrs/4)
tx.PushOutput(genAddress, coinsB, hrs/2)
tx.SignInputs([]cipher.SecKey{genSecret})
tx.UpdateHeader()
b, err := bc.NewBlockFromTransactions(coin.Transactions{tx}, bc.Time()+_incTime)
assert.Nil(t, err)
uxs, err := bc.ExecuteBlock(&b)
assert.Nil(t, err)
assert.Equal(t, len(uxs), 2)
return uxs
}
示例5: makeTransactionForChainWithHoursFee
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
}
示例6: makeTransactionWithSecret
func makeTransactionWithSecret(t *testing.T) (coin.Transaction, cipher.SecKey) {
tx := coin.Transaction{}
ux, s := makeUxOutWithSecret(t)
tx.PushInput(ux.Hash())
tx.SignInputs([]cipher.SecKey{s})
tx.PushOutput(makeAddress(), 10e6, 100)
tx.UpdateHeader()
return tx, s
}
示例7: CreateSpendingTransaction
// Creates a Transaction spending coins and hours from our coins
func CreateSpendingTransaction(wlt wallet.Wallet,
unconfirmed *UnconfirmedTxnPool, unspent *coin.UnspentPool,
headTime uint64, amt wallet.Balance, fee, burnFactor uint64,
dest cipher.Address) (coin.Transaction, error) {
txn := coin.Transaction{}
auxs := unspent.AllForAddresses(wlt.GetAddresses())
// Subtract pending spends from available
puxs := unconfirmed.SpendsForAddresses(unspent, wlt.GetAddressSet())
auxs = auxs.Sub(puxs)
// Determine which unspents to spend
spends, err := createSpends(headTime, auxs.Flatten(), amt, fee, burnFactor)
if err != nil {
return txn, err
}
// Add these unspents as tx inputs
toSign := make([]cipher.SecKey, len(spends))
spending := wallet.Balance{0, 0}
for i, au := range spends {
entry, exists := wlt.GetEntry(au.Body.Address)
if !exists {
log.Panic("On second thought, the wallet entry does not exist")
}
txn.PushInput(au.Hash())
toSign[i] = entry.Secret
spending.Coins += au.Body.Coins
spending.Hours += au.CoinHours(headTime)
}
// Determine how much change we get back, if any
_, changeHours, err := calculateBurnAndChange(spending.Hours,
amt.Hours, fee, burnFactor)
if err != nil {
// This should not occur, else createSpends is broken
return txn, err
}
change := wallet.NewBalance(spending.Coins-amt.Coins, changeHours)
// TODO -- send change to a new address
changeAddr := spends[0].Body.Address
if change.Coins == 0 {
if change.Hours > 0 {
msg := ("Have enough coins, but not enough to send coin hours " +
"change back. Would spend %d more hours than requested.")
return txn, fmt.Errorf(msg, change.Hours)
}
} else {
txn.PushOutput(changeAddr, change.Coins, change.Hours)
}
// Finalize the the transaction
txn.PushOutput(dest, amt.Coins, amt.Hours)
txn.SignInputs(toSign)
txn.UpdateHeader()
return txn, nil
}
示例8: CreateSpendingTransaction
//DEPRECATE
//deprecate dependency on wallet
// Creates a Transaction spending coins and hours from our coins
//MOVE SOMEWHERE ELSE
//Move to wallet or move to ???
func CreateSpendingTransaction(wlt wallet.Wallet,
unconfirmed *UnconfirmedTxnPool, unspent *coin.UnspentPool,
headTime uint64, amt wallet.Balance,
dest cipher.Address) (coin.Transaction, error) {
txn := coin.Transaction{}
auxs := unspent.AllForAddresses(wlt.GetAddresses())
// Subtract pending spends from available
puxs := unconfirmed.SpendsForAddresses(unspent, wlt.GetAddressSet())
auxs = auxs.Sub(puxs)
// Determine which unspents to spend
spends, err := createSpends(headTime, auxs.Flatten(), amt)
if err != nil {
return txn, err
}
// Add these unspents as tx inputs
toSign := make([]cipher.SecKey, len(spends))
spending := wallet.Balance{0, 0}
for i, au := range spends {
entry, exists := wlt.GetEntry(au.Body.Address)
if !exists {
log.Panic("On second thought, the wallet entry does not exist")
}
txn.PushInput(au.Hash())
toSign[i] = entry.Secret
spending.Coins += au.Body.Coins
spending.Hours += au.CoinHours(headTime)
}
//keep 1/4th of hours as change
//send half to each address
var changeHours uint64 = spending.Hours / 4
if amt.Coins == spending.Coins {
txn.PushOutput(dest, amt.Coins, changeHours/2)
txn.SignInputs(toSign)
txn.UpdateHeader()
return txn, nil
}
change := wallet.NewBalance(spending.Coins-amt.Coins, changeHours/2)
// TODO -- send change to a new address
changeAddr := spends[0].Body.Address
//create transaction
txn.PushOutput(changeAddr, change.Coins, change.Hours)
txn.PushOutput(dest, amt.Coins, changeHours/2)
txn.SignInputs(toSign)
txn.UpdateHeader()
return txn, nil
}
示例9: TestSpendsForAddresses
func TestSpendsForAddresses(t *testing.T) {
up := NewUnconfirmedTxnPool()
unspent := coin.NewUnspentPool()
addrs := make(map[cipher.Address]byte, 0)
n := 4
useAddrs := make([]cipher.Address, n)
for i, _ := range useAddrs {
useAddrs[i] = makeAddress()
}
useAddrs[1] = useAddrs[0]
for _, a := range useAddrs {
addrs[a] = byte(1)
}
// Make confirmed transactions to add to unspent pool
uxs := make(coin.UxArray, 0)
for i := 0; i < n; i++ {
txn := coin.Transaction{}
txn.PushInput(randSHA256())
txn.PushOutput(useAddrs[i], 10e6, 1000)
uxa := coin.CreateUnspents(coin.BlockHeader{}, txn)
for _, ux := range uxa {
unspent.Add(ux)
}
uxs = append(uxs, uxa...)
}
assert.Equal(t, len(uxs), 4)
// Make unconfirmed txns that spend those unspents
for i := 0; i < n; i++ {
txn := coin.Transaction{}
txn.PushInput(uxs[i].Hash())
txn.PushOutput(makeAddress(), 10e6, 1000)
ut := UnconfirmedTxn{
Txn: txn,
}
up.Txns[ut.Hash()] = ut
}
// Now look them up
assert.Equal(t, len(addrs), 3)
assert.Equal(t, len(up.Txns), 4)
auxs := up.SpendsForAddresses(&unspent, addrs)
assert.Equal(t, len(auxs), 3)
assert.Equal(t, len(auxs[useAddrs[0]]), 2)
assert.Equal(t, len(auxs[useAddrs[2]]), 1)
assert.Equal(t, len(auxs[useAddrs[3]]), 1)
assert.Equal(t, auxs[useAddrs[0]], coin.UxArray{uxs[0], uxs[1]})
assert.Equal(t, auxs[useAddrs[2]], coin.UxArray{uxs[2]})
assert.Equal(t, auxs[useAddrs[3]], coin.UxArray{uxs[3]})
}
示例10: makeMultipleOutputs
func makeMultipleOutputs(t *testing.T, bc *Blockchain) {
txn := coin.Transaction{}
ux := bc.GetUnspent().Array()[0]
txn.PushInput(ux.Hash())
txn.PushOutput(genAddress, 1e6, 100)
txn.PushOutput(genAddress, 2e6, 100)
txn.PushOutput(genAddress, _genCoins-3e6, 100)
txn.SignInputs([]cipher.SecKey{genSecret})
txn.UpdateHeader()
assert.Nil(t, txn.Verify())
assert.Nil(t, bc.VerifyTransaction(txn))
b, err := bc.NewBlockFromTransactions(coin.Transactions{txn},
bc.Time()+_incTime)
assert.Nil(t, err)
assertExecuteBlock(t, bc, b, txn)
}
示例11: newTransaction
// NewTransaction create skycoin transaction.
func newTransaction(utxos []unspentOut, keys []cipher.SecKey, outs []coin.TransactionOutput) (*coin.Transaction, error) {
tx := coin.Transaction{}
// keys := make([]cipher.SecKey, len(utxos))
for _, u := range utxos {
tx.PushInput(cipher.MustSHA256FromHex(u.Hash))
}
for _, o := range outs {
if (o.Coins % 1e6) != 0 {
return nil, errors.New("skycoin coins must be multiple of 1e6")
}
tx.PushOutput(o.Address, o.Coins, o.Hours)
}
// tx.Verify()
tx.SignInputs(keys)
tx.UpdateHeader()
return &tx, nil
}
示例12: addBlock
func addBlock(bc historydb.Blockchainer, td testData, tm uint64) (*coin.Block, *coin.Transaction, error) {
tx := coin.Transaction{}
// get unspent output
ux, err := getUx(bc, td.Vin.BlockSeq, td.Vin.TxID, td.Vin.Addr)
if err != nil {
return nil, nil, err
}
if ux == nil {
return nil, nil, errors.New("no unspent output")
}
tx.PushInput(ux.Hash())
for _, o := range td.Vouts {
addr, err := cipher.DecodeBase58Address(o.ToAddr)
if err != nil {
return nil, nil, err
}
tx.PushOutput(addr, o.Coins, o.Hours)
}
sigKey := cipher.MustSecKeyFromHex(td.Vin.SigKey)
tx.SignInputs([]cipher.SecKey{sigKey})
tx.UpdateHeader()
if err := bc.VerifyTransaction(tx); err != nil {
return nil, nil, err
}
preBlock := bc.GetBlock(td.PreBlockHash)
b := newBlock(*preBlock, tm, *bc.GetUnspent(), coin.Transactions{tx}, _feeCalc)
// uxs, err := bc.ExecuteBlock(&b)
_, err = bc.ExecuteBlock(&b)
if err != nil {
return nil, nil, err
}
return &b, &tx, nil
}
示例13: TestProcessTransactions
func TestProcessTransactions(t *testing.T) {
ft := FakeTree{}
bc := NewBlockchain(&ft, nil)
bc.CreateGenesisBlock(genAddress, _genCoins, _genTime)
fmt.Println("genesis time:", bc.GetGenesisBlock().Time())
assert.Equal(t, bc.Len(), uint64(1))
_, ux := addBlockToBlockchain(t, bc)
assert.Equal(t, bc.Len(), uint64(3))
// Invalid, no transactions in block
// arbitrating=false
txns, err := bc.processTransactions(coin.Transactions{}, false)
assert.Nil(t, txns)
assertError(t, err, "No transactions")
// arbitrating=true
txns, err = bc.processTransactions(coin.Transactions{}, true)
assert.Equal(t, len(txns), 0)
assert.Nil(t, err)
// Invalid, txn.Verify() fails
// TODO -- combine all txn.Verify() failures into one test
// method, and call it from here, from ExecuteBlock(), from
// Verify(), from VerifyTransaction()
txns = coin.Transactions{}
txn := coin.Transaction{}
txn.PushInput(ux.Hash())
txn.PushOutput(genAddress, 777, 100)
txn.SignInputs([]cipher.SecKey{genSecret})
txn.UpdateHeader()
txns = append(txns, txn)
// arbitrating=false
txns2, err := bc.processTransactions(txns, false)
assert.Nil(t, txns2)
assertError(t, err,
"Transaction outputs must be multiple of 1e6 base units")
// arbitrating=true
txns2, err = bc.processTransactions(txns, true)
assert.NotNil(t, txns2)
assert.Nil(t, err)
assert.Equal(t, len(txns2), 0)
// Invalid, duplicate unspent will be created by these txns
txn, _ = makeTransactionForChainWithHoursFee(t, bc, ux, genSecret, 100,
100)
txns = coin.Transactions{txn, txn}
// arbitrating=false
txns2, err = bc.processTransactions(txns, false)
assertError(t, err, "Duplicate unspent output across transactions")
assert.Nil(t, txns2)
// arbitrating=true. One of the offending transactions should be removed
txns2, err = bc.processTransactions(txns, true)
assert.Nil(t, err)
assert.Equal(t, len(txns2), 1)
assert.Equal(t, txns2[0], txn)
// Check that a new output will not collide with the existing pool
txn, _ = makeTransactionForChainWithHoursFee(t, bc, ux, genSecret, 100,
100)
txns = coin.Transactions{txn}
uxb := coin.UxBody{
SrcTransaction: txn.Hash(),
Coins: txn.Out[0].Coins,
Hours: txn.Out[0].Hours,
Address: txn.Out[0].Address,
}
bc.GetUnspent().Add(coin.UxOut{Body: uxb})
// arbitrating=false
txns2, err = bc.processTransactions(txns, false)
assertError(t, err, "New unspent collides with existing unspent")
assert.Nil(t, txns2)
// arbitrating=true
txns2, err = bc.processTransactions(txns, true)
assert.Equal(t, len(txns2), 0)
assert.NotNil(t, txns2)
assert.Nil(t, err)
// Spending of duplicate inputs being spent across txns
txn, _ = makeTransactionForChainWithHoursFee(t, bc, ux, genSecret, 100,
100)
txn2, _ := makeTransactionForChainWithHoursFee(t, bc, ux, genSecret, 100,
100)
txn2.Out = nil
txn2.PushOutput(makeAddress(), 1e6, 100)
txn2.PushOutput(makeAddress(), ux.Body.Coins-1e6, 100)
txn2.Sigs = nil
txn2.SignInputs([]cipher.SecKey{genSecret})
txn2.UpdateHeader()
txns = coin.SortTransactions(coin.Transactions{txn, txn2}, bc.TransactionFee)
// arbitrating=false
txns2, err = bc.processTransactions(txns, false)
assertError(t, err, "Cannot spend output twice in the same block")
assert.Nil(t, txns2)
// arbitrating=true
txns2, err = bc.processTransactions(txns, true)
assert.Nil(t, err)
assert.Equal(t, len(txns2), 1)
assert.Equal(t, txns2[0], txns[0])
}
示例14: TestVerifyTransactionSpending
func TestVerifyTransactionSpending(t *testing.T) {
ft := FakeTree{}
bc := NewBlockchain(&ft, nil)
bc.CreateGenesisBlock(genAddress, _genCoins, _genTime)
// Overspending hours
tx := coin.Transaction{}
uxs := bc.GetUnspent().Array()
tx.PushInput(uxs[0].Hash())
tx.PushOutput(genAddress, 1e6, uxs[0].Body.Hours)
tx.PushOutput(genAddress, uxs[0].Body.Coins-1e6, 1)
uxIn, err := bc.GetUnspent().GetMultiple(tx.In)
assert.Nil(t, err)
uxOut := coin.CreateUnspents(bc.Head().Head, tx)
assertError(t, coin.VerifyTransactionSpending(bc.Time(), uxIn, uxOut),
"Insufficient coin hours")
// add block to blockchain.
_, ux := addBlockToBlockchain(t, bc)
// addBlockToBlockchain(t, bc)
// Valid
tx, _ = makeTransactionForChainWithHoursFee(t, bc, ux, genSecret, 100, 50)
uxIn, err = bc.GetUnspent().GetMultiple(tx.In)
assert.Nil(t, err)
uxOut = coin.CreateUnspents(bc.Head().Head, tx)
assert.Nil(t, coin.VerifyTransactionSpending(bc.Time(), uxIn, uxOut))
// Destroying coins
tx = coin.Transaction{}
tx.PushInput(ux.Hash())
tx.PushOutput(genAddress, 1e6, 100)
tx.PushOutput(genAddress, 10e6, 100)
uxIn, err = bc.GetUnspent().GetMultiple(tx.In)
assert.Nil(t, err)
uxOut = coin.CreateUnspents(bc.Head().Head, tx)
err = coin.VerifyTransactionSpending(bc.Time(), uxIn, uxOut)
assert.NotNil(t, err)
assert.Equal(t, err.Error(),
"Transactions may not create or destroy coins")
assertError(t, coin.VerifyTransactionSpending(bc.Time(), uxIn, uxOut),
"Transactions may not create or destroy coins")
// Insufficient coins
tx = coin.Transaction{}
tx.PushInput(ux.Hash())
p, s := cipher.GenerateKeyPair()
a := cipher.AddressFromPubKey(p)
coins := ux.Body.Coins
assert.True(t, coins > 1e6)
tx.PushOutput(a, 1e6, 100)
tx.PushOutput(genAddress, coins-1e6, 100)
tx.SignInputs([]cipher.SecKey{genSecret})
tx.UpdateHeader()
b, err := bc.NewBlockFromTransactions(coin.Transactions{tx}, bc.Time()+_incTime)
assert.Nil(t, err)
uxs, err = bc.ExecuteBlock(&b)
assert.Nil(t, err)
tx = coin.Transaction{}
tx.PushInput(uxs[0].Hash())
tx.PushOutput(a, 10e6, 1)
tx.SignInputs([]cipher.SecKey{s})
tx.UpdateHeader()
uxIn, err = bc.GetUnspent().GetMultiple(tx.In)
assert.Nil(t, err)
uxOut = coin.CreateUnspents(bc.Head().Head, tx)
assertError(t, coin.VerifyTransactionSpending(bc.Time(), uxIn, uxOut),
"Insufficient coins")
}
示例15: TestNewBlockFromTransactions
func TestNewBlockFromTransactions(t *testing.T) {
ft := FakeTree{}
bc := NewBlockchain(&ft, nil)
gb := bc.CreateGenesisBlock(genAddress, _genCoins, _genTime)
// gb.Head.Version = 0x0F
// bc.Blocks[0] = gb
// assert.Equal(t, bc.GetGenesisBlock().Head.Version, uint32(0x0F))
assert.Equal(t, bc.Len(), uint64(1))
_, ux := addBlockToBlockchain(t, bc)
assert.Equal(t, bc.Len(), uint64(3))
// No transactions
_, err := bc.NewBlockFromTransactions(coin.Transactions{},
bc.Time()+_incTime)
assertError(t, err, "No transactions")
assert.Equal(t, bc.Len(), uint64(3))
// Bad currentTime, must be greater than head time
fee := uint64(100)
txn, _ := makeTransactionForChainWithHoursFee(t, bc, ux, genSecret, 100,
fee)
txns := coin.Transactions{txn}
assert.Panics(t, func() {
bc.NewBlockFromTransactions(txns, bc.Time())
})
// Valid transaction
hrs := ux.CoinHours(bc.Time())
seq := bc.Head().Head.BkSeq
b, err := bc.NewBlockFromTransactions(txns, bc.Time()+_incTime)
assert.Nil(t, err)
assert.Equal(t, len(b.Body.Transactions), 1)
assert.Equal(t, b.Body.Transactions[0], txn)
assert.Equal(t, b.Head.BkSeq, seq+1)
assert.Equal(t, b.Head.Time, bc.Time()+_incTime)
assert.Equal(t, b.Head.Version, gb.Head.Version)
assert.Equal(t, b.Head.Fee, fee)
assert.Equal(t, b.Head.Fee, hrs-txn.OutputHours())
assert.NotEqual(t, b.Head.Fee, uint64(0))
// Invalid transaction
txn.InnerHash = cipher.SHA256{}
txns = coin.Transactions{txn}
_, err = bc.NewBlockFromTransactions(txns, bc.Time()+_incTime)
assertError(t, err, "Invalid header hash")
// Multiple transactions, sorted
// First, split our genesis block into two, so we can make 2 valid txns
uxs := splitUnspent(t, bc, ux)
// tNow, make two valid txns
txn = coin.Transaction{}
txn.PushInput(uxs[0].Hash())
txn.PushOutput(genAddress, uxs[0].Body.Coins, uxs[0].Body.Hours)
txn.SignInputs([]cipher.SecKey{genSecret})
txn.UpdateHeader()
txn2 := coin.Transaction{}
txn2.PushInput(uxs[1].Hash())
txn2.PushOutput(genAddress, uxs[1].Body.Coins, uxs[1].Body.Hours)
txn2.SignInputs([]cipher.SecKey{genSecret})
txn2.UpdateHeader()
// Combine them and sort
txns = coin.Transactions{txn, txn2}
txns = coin.SortTransactions(txns, bc.TransactionFee)
b, err = bc.NewBlockFromTransactions(txns, bc.Time()+_incTime)
assert.Nil(t, err)
assert.Equal(t, len(b.Body.Transactions), 2)
assert.Equal(t, b.Body.Transactions, txns)
// Order should be preserved
txns2 := coin.Transactions{txn, txn2}
sTxns := coin.NewSortableTransactions(txns2, bc.TransactionFee)
if sTxns.IsSorted() {
txns2[0], txns2[1] = txns2[1], txns2[0]
}
b, err = bc.NewBlockFromTransactions(txns2, bc.Time()+_incTime)
assert.Nil(t, err)
assert.Equal(t, len(b.Body.Transactions), 2)
assert.Equal(t, b.Body.Transactions, txns2)
}