本文整理匯總了Golang中github.com/NebulousLabs/Sia/types.Transaction.SiacoinOutputID方法的典型用法代碼示例。如果您正苦於以下問題:Golang Transaction.SiacoinOutputID方法的具體用法?Golang Transaction.SiacoinOutputID怎麽用?Golang Transaction.SiacoinOutputID使用的例子?那麽, 這裏精選的方法代碼示例或許可以為您提供幫助。您也可以進一步了解該方法所在類github.com/NebulousLabs/Sia/types.Transaction
的用法示例。
在下文中一共展示了Transaction.SiacoinOutputID方法的10個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於係統推薦出更棒的Golang代碼示例。
示例1: TestApplySiacoinOutputs
// TestApplySiacoinOutputs probes the applySiacoinOutput method of the
// consensus set.
func TestApplySiacoinOutputs(t *testing.T) {
if testing.Short() {
t.SkipNow()
}
cst, err := createConsensusSetTester("TestApplySiacoinOutputs")
if err != nil {
t.Fatal(err)
}
// Create a block node to use with application.
bn := new(blockNode)
// Apply a transaction with a single siacoin output.
txn := types.Transaction{
SiacoinOutputs: []types.SiacoinOutput{{}},
}
cst.cs.applySiacoinOutputs(bn, txn)
scoid := txn.SiacoinOutputID(0)
_, exists := cst.cs.siacoinOutputs[scoid]
if !exists {
t.Error("Failed to create siacoin output")
}
if len(cst.cs.siacoinOutputs) != 3 { // 3 because createConsensusSetTester has 2 initially.
t.Error("siacoin outputs not correctly updated")
}
if len(bn.siacoinOutputDiffs) != 1 {
t.Error("block node was not updated for single element transaction")
}
if bn.siacoinOutputDiffs[0].Direction != modules.DiffApply {
t.Error("wrong diff direction applied when creating a siacoin output")
}
if bn.siacoinOutputDiffs[0].ID != scoid {
t.Error("wrong id used when creating a siacoin output")
}
// Apply a transaction with 2 siacoin outputs.
txn = types.Transaction{
SiacoinOutputs: []types.SiacoinOutput{
{Value: types.NewCurrency64(1)},
{Value: types.NewCurrency64(2)},
},
}
cst.cs.applySiacoinOutputs(bn, txn)
scoid0 := txn.SiacoinOutputID(0)
scoid1 := txn.SiacoinOutputID(1)
_, exists = cst.cs.siacoinOutputs[scoid0]
if !exists {
t.Error("Failed to create siacoin output")
}
_, exists = cst.cs.siacoinOutputs[scoid1]
if !exists {
t.Error("Failed to create siacoin output")
}
if len(cst.cs.siacoinOutputs) != 5 { // 5 because createConsensusSetTester has 2 initially.
t.Error("siacoin outputs not correctly updated")
}
if len(bn.siacoinOutputDiffs) != 3 {
t.Error("block node was not updated correctly")
}
}
示例2: applySiacoinOutputs
// applySiacoinOutputs takes all of the siacoin outputs in a transaction and
// applies them to the state, updating the diffs in the processed block.
func applySiacoinOutputs(tx *bolt.Tx, pb *processedBlock, t types.Transaction) {
// Add all siacoin outputs to the unspent siacoin outputs list.
for i, sco := range t.SiacoinOutputs {
scoid := t.SiacoinOutputID(uint64(i))
scod := modules.SiacoinOutputDiff{
Direction: modules.DiffApply,
ID: scoid,
SiacoinOutput: sco,
}
pb.SiacoinOutputDiffs = append(pb.SiacoinOutputDiffs, scod)
commitSiacoinOutputDiff(tx, scod, modules.DiffApply)
}
}
示例3: removeSiacoinOutputs
// removeSiacoinOutputs removes all of the siacoin outputs of a transaction
// from the unconfirmed consensus set.
func (tp *TransactionPool) removeSiacoinOutputs(t types.Transaction) {
for i, _ := range t.SiacoinOutputs {
scoid := t.SiacoinOutputID(i)
// Sanity check - the output should exist in the unconfirmed set as
// there should be no transaction dependents who have spent the output.
if build.DEBUG {
_, exists := tp.siacoinOutputs[scoid]
if !exists {
panic("trying to delete missing siacoin output")
}
}
delete(tp.siacoinOutputs, scoid)
}
}
示例4: applySiacoinOutputs
// applySiacoinOutputs takes all of the siacoin outputs in a transaction and
// applies them to the state, updating the diffs in the processed block.
func (cs *ConsensusSet) applySiacoinOutputs(tx *bolt.Tx, pb *processedBlock, t types.Transaction) error {
// Add all siacoin outputs to the unspent siacoin outputs list.
scoBucket := tx.Bucket(SiacoinOutputs)
for i, sco := range t.SiacoinOutputs {
scoid := t.SiacoinOutputID(i)
scod := modules.SiacoinOutputDiff{
Direction: modules.DiffApply,
ID: scoid,
SiacoinOutput: sco,
}
pb.SiacoinOutputDiffs = append(pb.SiacoinOutputDiffs, scod)
err := cs.commitBucketSiacoinOutputDiff(scoBucket, scod, modules.DiffApply)
if err != nil {
return err
}
}
return nil
}
示例5: applySiacoinOutputs
// applySiacoinOutputs takes all of the siacoin outputs in a transaction and
// applies them to the state, updating the diffs in the block node.
func (cs *State) applySiacoinOutputs(bn *blockNode, t types.Transaction) {
// Add all siacoin outputs to the unspent siacoin outputs list.
for i, sco := range t.SiacoinOutputs {
// Sanity check - the output should not exist within the state.
scoid := t.SiacoinOutputID(i)
if build.DEBUG {
_, exists := cs.siacoinOutputs[scoid]
if exists {
panic(ErrMisuseApplySiacoinOutput)
}
}
scod := modules.SiacoinOutputDiff{
Direction: modules.DiffApply,
ID: scoid,
SiacoinOutput: sco,
}
bn.siacoinOutputDiffs = append(bn.siacoinOutputDiffs, scod)
cs.commitSiacoinOutputDiff(scod, modules.DiffApply)
}
}
示例6: TestPartialConfirmationWeave
// TestPartialConfirmationWeave checks that the transaction pool correctly
// accepts a transaction set which has parents that have been accepted by the
// consensus set but not the whole set has been accepted by the consensus set,
// this time weaving the dependencies, such that the first transaction is not
// in the consensus set, the second is, and the third has both as dependencies.
func TestPartialConfirmationWeave(t *testing.T) {
if testing.Short() {
t.SkipNow()
}
tpt, err := createTpoolTester("TestPartialConfirmation")
if err != nil {
t.Fatal(err)
}
defer tpt.Close()
// Step 1: create an output to the empty address in a tx.
// Step 2: create a second output to the empty address in another tx.
// Step 3: create a transaction using both those outputs.
// Step 4: mine the txn set in step 2
// Step 5: Submit the complete set.
// Create a transaction with a single output to a fully controlled address.
emptyUH := types.UnlockConditions{}.UnlockHash()
builder1 := tpt.wallet.StartTransaction()
funding1 := types.NewCurrency64(1e9)
err = builder1.FundSiacoins(funding1)
if err != nil {
t.Fatal(err)
}
scOutput1 := types.SiacoinOutput{
Value: funding1,
UnlockHash: emptyUH,
}
i1 := builder1.AddSiacoinOutput(scOutput1)
tSet1, err := builder1.Sign(true)
if err != nil {
t.Fatal(err)
}
// Submit to the transaction pool and mine the block, to minimize
// complexity.
err = tpt.tpool.AcceptTransactionSet(tSet1)
if err != nil {
t.Fatal(err)
}
_, err = tpt.miner.AddBlock()
if err != nil {
t.Fatal(err)
}
// Create a second output to the fully controlled address, to fund the
// second transaction in the weave.
builder2 := tpt.wallet.StartTransaction()
funding2 := types.NewCurrency64(2e9)
err = builder2.FundSiacoins(funding2)
if err != nil {
t.Fatal(err)
}
scOutput2 := types.SiacoinOutput{
Value: funding2,
UnlockHash: emptyUH,
}
i2 := builder2.AddSiacoinOutput(scOutput2)
tSet2, err := builder2.Sign(true)
if err != nil {
t.Fatal(err)
}
// Submit to the transaction pool and mine the block, to minimize
// complexity.
err = tpt.tpool.AcceptTransactionSet(tSet2)
if err != nil {
t.Fatal(err)
}
_, err = tpt.miner.AddBlock()
if err != nil {
t.Fatal(err)
}
// Create a passthrough transaction for output1 and output2, so that they
// can be used as unconfirmed dependencies.
txn1 := types.Transaction{
SiacoinInputs: []types.SiacoinInput{{
ParentID: tSet1[len(tSet1)-1].SiacoinOutputID(i1),
}},
SiacoinOutputs: []types.SiacoinOutput{{
Value: funding1,
UnlockHash: emptyUH,
}},
}
txn2 := types.Transaction{
SiacoinInputs: []types.SiacoinInput{{
ParentID: tSet2[len(tSet2)-1].SiacoinOutputID(i2),
}},
SiacoinOutputs: []types.SiacoinOutput{{
Value: funding2,
UnlockHash: emptyUH,
}},
}
// Create a child transaction that depends on inputs from both txn1 and
// txn2.
//.........這裏部分代碼省略.........
示例7: 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(),
//.........這裏部分代碼省略.........
示例8: buildExplorerTransaction
// buildExplorerTransaction takes a transaction and the height + id of the
// block it appears in an uses that to build an explorer transaction.
func (srv *Server) buildExplorerTransaction(height types.BlockHeight, parent types.BlockID, txn types.Transaction) (et ExplorerTransaction) {
// Get the header information for the transaction.
et.ID = txn.ID()
et.Height = height
et.Parent = parent
et.RawTransaction = txn
// Add the siacoin outputs that correspond with each siacoin input.
for _, sci := range txn.SiacoinInputs {
sco, exists := srv.explorer.SiacoinOutput(sci.ParentID)
if build.DEBUG && !exists {
panic("could not find corresponding siacoin output")
}
et.SiacoinInputOutputs = append(et.SiacoinInputOutputs, sco)
}
for i := range txn.SiacoinOutputs {
et.SiacoinOutputIDs = append(et.SiacoinOutputIDs, txn.SiacoinOutputID(uint64(i)))
}
// Add all of the valid and missed proof ids as extra data to the file
// contracts.
for i, fc := range txn.FileContracts {
fcid := txn.FileContractID(uint64(i))
var fcvpoids []types.SiacoinOutputID
var fcmpoids []types.SiacoinOutputID
for j := range fc.ValidProofOutputs {
fcvpoids = append(fcvpoids, fcid.StorageProofOutputID(types.ProofValid, uint64(j)))
}
for j := range fc.MissedProofOutputs {
fcmpoids = append(fcmpoids, fcid.StorageProofOutputID(types.ProofMissed, uint64(j)))
}
et.FileContractIDs = append(et.FileContractIDs, fcid)
et.FileContractValidProofOutputIDs = append(et.FileContractValidProofOutputIDs, fcvpoids)
et.FileContractMissedProofOutputIDs = append(et.FileContractMissedProofOutputIDs, fcmpoids)
}
// Add all of the valid and missed proof ids as extra data to the file
// contract revisions.
for _, fcr := range txn.FileContractRevisions {
var fcrvpoids []types.SiacoinOutputID
var fcrmpoids []types.SiacoinOutputID
for j := range fcr.NewValidProofOutputs {
fcrvpoids = append(fcrvpoids, fcr.ParentID.StorageProofOutputID(types.ProofValid, uint64(j)))
}
for j := range fcr.NewMissedProofOutputs {
fcrmpoids = append(fcrmpoids, fcr.ParentID.StorageProofOutputID(types.ProofMissed, uint64(j)))
}
et.FileContractValidProofOutputIDs = append(et.FileContractValidProofOutputIDs, fcrvpoids)
et.FileContractMissedProofOutputIDs = append(et.FileContractMissedProofOutputIDs, fcrmpoids)
}
// Add all of the output ids and outputs corresponding with each storage
// proof.
for _, sp := range txn.StorageProofs {
fileContract, fileContractRevisions, fileContractExists, _ := srv.explorer.FileContractHistory(sp.ParentID)
if !fileContractExists && build.DEBUG {
panic("could not find a file contract connected with a storage proof")
}
var storageProofOutputs []types.SiacoinOutput
if len(fileContractRevisions) > 0 {
storageProofOutputs = fileContractRevisions[len(fileContractRevisions)-1].NewValidProofOutputs
} else {
storageProofOutputs = fileContract.ValidProofOutputs
}
var storageProofOutputIDs []types.SiacoinOutputID
for i := range storageProofOutputs {
storageProofOutputIDs = append(storageProofOutputIDs, sp.ParentID.StorageProofOutputID(types.ProofValid, uint64(i)))
}
et.StorageProofOutputIDs = append(et.StorageProofOutputIDs, storageProofOutputIDs)
et.StorageProofOutputs = append(et.StorageProofOutputs, storageProofOutputs)
}
// Add the siafund outputs that correspond to each siacoin input.
for _, sci := range txn.SiafundInputs {
sco, exists := srv.explorer.SiafundOutput(sci.ParentID)
if build.DEBUG && !exists {
panic("could not find corresponding siafund output")
}
et.SiafundInputOutputs = append(et.SiafundInputOutputs, sco)
}
for i := range txn.SiafundOutputs {
et.SiafundOutputIDs = append(et.SiafundOutputIDs, txn.SiafundOutputID(uint64(i)))
}
for _, sfi := range txn.SiafundInputs {
et.SiaClaimOutputIDs = append(et.SiaClaimOutputIDs, sfi.ParentID.SiaClaimOutputID())
}
return et
}
示例9: addTransaction
// addTransaction is called from addBlockDB, and delegates the adding
// of information to the database to the functions defined above
func (tx *boltTx) addTransaction(txn types.Transaction) {
// Store this for quick lookup
txid := txn.ID()
// Append each input to the list of modifications
for _, input := range txn.SiacoinInputs {
tx.addAddress(input.UnlockConditions.UnlockHash(), txid)
tx.addSiacoinInput(input.ParentID, txid)
}
// Handle all the transaction outputs
for i, output := range txn.SiacoinOutputs {
tx.addAddress(output.UnlockHash, txid)
tx.addNewOutput(txn.SiacoinOutputID(uint64(i)), txid)
}
// Handle each file contract individually
for i, contract := range txn.FileContracts {
fcid := txn.FileContractID(uint64(i))
tx.addNewHash("FileContracts", hashFilecontract, crypto.Hash(fcid), fcInfo{
Contract: txid,
})
for j, output := range contract.ValidProofOutputs {
tx.addAddress(output.UnlockHash, txid)
tx.addNewOutput(fcid.StorageProofOutputID(true, uint64(j)), txid)
}
for j, output := range contract.MissedProofOutputs {
tx.addAddress(output.UnlockHash, txid)
tx.addNewOutput(fcid.StorageProofOutputID(false, uint64(j)), txid)
}
tx.addAddress(contract.UnlockHash, txid)
}
// Update the list of revisions
for _, revision := range txn.FileContractRevisions {
tx.addFcRevision(revision.ParentID, txid)
// Note the old outputs will still be there in the
// database. This is to provide information to the
// people who may just need it.
for i, output := range revision.NewValidProofOutputs {
tx.addAddress(output.UnlockHash, txid)
tx.addNewOutput(revision.ParentID.StorageProofOutputID(true, uint64(i)), txid)
}
for i, output := range revision.NewMissedProofOutputs {
tx.addAddress(output.UnlockHash, txid)
tx.addNewOutput(revision.ParentID.StorageProofOutputID(false, uint64(i)), txid)
}
tx.addAddress(revision.NewUnlockHash, txid)
}
// Update the list of storage proofs
for _, proof := range txn.StorageProofs {
tx.addFcProof(proof.ParentID, txid)
}
// Append all the siafund inputs to the modification list
for _, input := range txn.SiafundInputs {
tx.addSiafundInput(input.ParentID, txid)
}
// Handle all the siafund outputs
for i, output := range txn.SiafundOutputs {
tx.addAddress(output.UnlockHash, txid)
tx.addNewSFOutput(txn.SiafundOutputID(uint64(i)), txid)
}
tx.putObject("Hashes", txid, hashTransaction)
}
示例10: 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.
//.........這裏部分代碼省略.........