本文整理匯總了Golang中github.com/NebulousLabs/Sia/types.Transaction.SiacoinInputs方法的典型用法代碼示例。如果您正苦於以下問題:Golang Transaction.SiacoinInputs方法的具體用法?Golang Transaction.SiacoinInputs怎麽用?Golang Transaction.SiacoinInputs使用的例子?那麽, 這裏精選的方法代碼示例或許可以為您提供幫助。您也可以進一步了解該方法所在類github.com/NebulousLabs/Sia/types.Transaction
的用法示例。
在下文中一共展示了Transaction.SiacoinInputs方法的2個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於係統推薦出更棒的Golang代碼示例。
示例1: FundSiacoins
// FundSiacoins will add a siacoin input of exaclty 'amount' to the
// transaction. A parent transaction may be needed to achieve an input with the
// correct value. The siacoin input will not be signed until 'Sign' is called
// on the transaction builder.
func (tb *transactionBuilder) FundSiacoins(amount types.Currency) error {
tb.wallet.mu.Lock()
defer tb.wallet.mu.Unlock()
// Collect a value-sorted set of siacoin outputs.
var so sortedOutputs
for scoid, sco := range tb.wallet.siacoinOutputs {
so.ids = append(so.ids, scoid)
so.outputs = append(so.outputs, sco)
}
// Add all of the unconfirmed outputs as well.
for _, upt := range tb.wallet.unconfirmedProcessedTransactions {
for i, sco := range upt.Transaction.SiacoinOutputs {
// Determine if the output belongs to the wallet.
_, exists := tb.wallet.keys[sco.UnlockHash]
if !exists {
continue
}
so.ids = append(so.ids, upt.Transaction.SiacoinOutputID(uint64(i)))
so.outputs = append(so.outputs, sco)
}
}
sort.Sort(sort.Reverse(so))
// Create and fund a parent transaction that will add the correct amount of
// siacoins to the transaction.
var fund types.Currency
// potentialFund tracks the balance of the wallet including outputs that
// have been spent in other unconfirmed transactions recently. This is to
// provide the user with a more useful error message in the event that they
// are overspending.
var potentialFund types.Currency
parentTxn := types.Transaction{}
var spentScoids []types.SiacoinOutputID
for i := range so.ids {
scoid := so.ids[i]
sco := so.outputs[i]
// Check that this output has not recently been spent by the wallet.
spendHeight := tb.wallet.spentOutputs[types.OutputID(scoid)]
// Prevent an underflow error.
allowedHeight := tb.wallet.consensusSetHeight - RespendTimeout
if tb.wallet.consensusSetHeight < RespendTimeout {
allowedHeight = 0
}
if spendHeight > allowedHeight {
potentialFund = potentialFund.Add(sco.Value)
continue
}
outputUnlockConditions := tb.wallet.keys[sco.UnlockHash].UnlockConditions
if tb.wallet.consensusSetHeight < outputUnlockConditions.Timelock {
continue
}
// Add a siacoin input for this output.
sci := types.SiacoinInput{
ParentID: scoid,
UnlockConditions: outputUnlockConditions,
}
parentTxn.SiacoinInputs = append(parentTxn.SiacoinInputs, sci)
spentScoids = append(spentScoids, scoid)
// Add the output to the total fund
fund = fund.Add(sco.Value)
potentialFund = potentialFund.Add(sco.Value)
if fund.Cmp(amount) >= 0 {
break
}
}
if potentialFund.Cmp(amount) >= 0 && fund.Cmp(amount) < 0 {
return modules.ErrPotentialDoubleSpend
}
if fund.Cmp(amount) < 0 {
return modules.ErrLowBalance
}
// Create and add the output that will be used to fund the standard
// transaction.
parentUnlockConditions, err := tb.wallet.nextPrimarySeedAddress()
if err != nil {
return err
}
exactOutput := types.SiacoinOutput{
Value: amount,
UnlockHash: parentUnlockConditions.UnlockHash(),
}
parentTxn.SiacoinOutputs = append(parentTxn.SiacoinOutputs, exactOutput)
// Create a refund output if needed.
if amount.Cmp(fund) != 0 {
refundUnlockConditions, err := tb.wallet.nextPrimarySeedAddress()
if err != nil {
return err
}
refundOutput := types.SiacoinOutput{
Value: fund.Sub(amount),
UnlockHash: refundUnlockConditions.UnlockHash(),
//.........這裏部分代碼省略.........
示例2: FundTransaction
// FundTransaction adds siacoins to a transaction that the wallet knows how to
// spend. The exact amount of coins are always added, and this is achieved by
// creating two transactions. The first transaciton, the parent, spends a set
// of outputs that add up to at least the desired amount, and then creates a
// single output of the exact amount and a second refund output.
func (w *Wallet) FundTransaction(id string, amount types.Currency) (t types.Transaction, err error) {
counter := w.mu.Lock()
defer w.mu.Unlock(counter)
// Create a parent transaction and supply it with enough inputs to cover
// 'amount'.
parentTxn := types.Transaction{}
fundingOutputs, fundingTotal, err := w.findOutputs(amount)
if err != nil {
return
}
for _, output := range fundingOutputs {
output.age = w.age
key := w.keys[output.output.UnlockHash]
newInput := types.SiacoinInput{
ParentID: output.id,
UnlockConditions: key.unlockConditions,
}
parentTxn.SiacoinInputs = append(parentTxn.SiacoinInputs, newInput)
}
// Create and add the output that will be used to fund the standard
// transaction.
parentDest, parentSpendConds, err := w.coinAddress(false) // false indicates that the address should not be visible to the user
exactOutput := types.SiacoinOutput{
Value: amount,
UnlockHash: parentDest,
}
parentTxn.SiacoinOutputs = append(parentTxn.SiacoinOutputs, exactOutput)
// Create a refund output if needed.
if amount.Cmp(fundingTotal) != 0 {
var refundDest types.UnlockHash
refundDest, _, err = w.coinAddress(false) // false indicates that the address should not be visible to the user
if err != nil {
return
}
refundOutput := types.SiacoinOutput{
Value: fundingTotal.Sub(amount),
UnlockHash: refundDest,
}
parentTxn.SiacoinOutputs = append(parentTxn.SiacoinOutputs, refundOutput)
}
// Sign all of the inputs to the parent trancstion.
coveredFields := types.CoveredFields{WholeTransaction: true}
for _, input := range parentTxn.SiacoinInputs {
sig := types.TransactionSignature{
ParentID: crypto.Hash(input.ParentID),
CoveredFields: coveredFields,
PublicKeyIndex: 0,
}
parentTxn.TransactionSignatures = append(parentTxn.TransactionSignatures, sig)
// Hash the transaction according to the covered fields.
coinAddress := input.UnlockConditions.UnlockHash()
sigIndex := len(parentTxn.TransactionSignatures) - 1
secKey := w.keys[coinAddress].secretKey
sigHash := parentTxn.SigHash(sigIndex)
// Get the signature.
var encodedSig crypto.Signature
encodedSig, err = crypto.SignHash(sigHash, secKey)
if err != nil {
return
}
parentTxn.TransactionSignatures[sigIndex].Signature = types.Signature(encodedSig[:])
}
// Add the exact output to the wallet's knowledgebase before releasing the
// lock, to prevent the wallet from using the exact output elsewhere.
key := w.keys[parentSpendConds.UnlockHash()]
key.outputs[parentTxn.SiacoinOutputID(0)] = &knownOutput{
id: parentTxn.SiacoinOutputID(0),
output: exactOutput,
spendable: true,
age: w.age,
}
// Send the transaction to the transaction pool.
err = w.tpool.AcceptTransaction(parentTxn)
if err != nil {
return
}
// Get the transaction that was originally meant to be funded.
openTxn, exists := w.transactions[id]
if !exists {
err = ErrInvalidID
return
}
txn := openTxn.transaction
// Add the exact output.
//.........這裏部分代碼省略.........