本文整理匯總了Golang中github.com/NebulousLabs/Sia/types.Currency.Sub方法的典型用法代碼示例。如果您正苦於以下問題:Golang Currency.Sub方法的具體用法?Golang Currency.Sub怎麽用?Golang Currency.Sub使用的例子?那麽, 這裏精選的方法代碼示例或許可以為您提供幫助。您也可以進一步了解該方法所在類github.com/NebulousLabs/Sia/types.Currency
的用法示例。
在下文中一共展示了Currency.Sub方法的7個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於係統推薦出更棒的Golang代碼示例。
示例1: nodeAtWeight
// nodeAtWeight grabs an element in the tree that appears at the given weight.
// Though the tree has an arbitrary sorting, a sufficiently random weight will
// pull a random element. The tree is searched through in a post-ordered way.
func (hn *hostNode) nodeAtWeight(weight types.Currency) (*hostNode, error) {
// Sanity check - weight must be less than the total weight of the tree.
if weight.Cmp(hn.weight) > 0 {
return nil, errOverweight
}
// Check if the left or right child should be returned.
if hn.left != nil {
if weight.Cmp(hn.left.weight) < 0 {
return hn.left.nodeAtWeight(weight)
}
weight = weight.Sub(hn.left.weight) // Search from 0th index of right side.
}
if hn.right != nil && weight.Cmp(hn.right.weight) < 0 {
return hn.right.nodeAtWeight(weight)
}
// Sanity check
if build.DEBUG && !hn.taken {
build.Critical("nodeAtWeight should not be returning a nil entry")
}
// Return the root entry.
return hn, nil
}
示例2: wallettransactionscmd
// wallettransactionscmd lists all of the transactions related to the wallet,
// providing a net flow of siacoins and siafunds for each.
func wallettransactionscmd() {
wtg := new(api.WalletTransactionsGET)
err := getAPI("/wallet/transactions?startheight=0&endheight=10000000", wtg)
if err != nil {
fmt.Println("Could not fetch transaction history:", err)
return
}
fmt.Println(" [height] [transaction id] [net siacoins] [net siafunds]")
txns := append(wtg.ConfirmedTransactions, wtg.UnconfirmedTransactions...)
for _, txn := range txns {
// Determine the number of outgoing siacoins and siafunds.
var outgoingSiacoins types.Currency
var outgoingSiafunds types.Currency
for _, input := range txn.Inputs {
if input.FundType == types.SpecifierSiacoinInput && input.WalletAddress {
outgoingSiacoins = outgoingSiacoins.Add(input.Value)
}
if input.FundType == types.SpecifierSiafundInput && input.WalletAddress {
outgoingSiafunds = outgoingSiafunds.Add(input.Value)
}
}
// Determine the number of incoming siacoins and siafunds.
var incomingSiacoins types.Currency
var incomingSiafunds types.Currency
for _, output := range txn.Outputs {
if output.FundType == types.SpecifierMinerPayout {
incomingSiacoins = incomingSiacoins.Add(output.Value)
}
if output.FundType == types.SpecifierSiacoinOutput && output.WalletAddress {
incomingSiacoins = incomingSiacoins.Add(output.Value)
}
if output.FundType == types.SpecifierSiafundOutput && output.WalletAddress {
incomingSiafunds = incomingSiafunds.Add(output.Value)
}
}
// Convert the siacoins to a float.
incomingSiacoinsFloat, _ := new(big.Rat).SetFrac(incomingSiacoins.Big(), types.SiacoinPrecision.Big()).Float64()
outgoingSiacoinsFloat, _ := new(big.Rat).SetFrac(outgoingSiacoins.Big(), types.SiacoinPrecision.Big()).Float64()
// Print the results.
if txn.ConfirmationHeight < 1e9 {
fmt.Printf("%12v", txn.ConfirmationHeight)
} else {
fmt.Printf(" unconfirmed")
}
fmt.Printf("%67v%15.2f SC", txn.TransactionID, incomingSiacoinsFloat-outgoingSiacoinsFloat)
// For siafunds, need to avoid having a negative types.Currency.
if incomingSiafunds.Cmp(outgoingSiafunds) >= 0 {
fmt.Printf("%14v SF\n", incomingSiafunds.Sub(outgoingSiafunds))
} else {
fmt.Printf("-%14v SF\n", outgoingSiafunds.Sub(incomingSiafunds))
}
}
}
示例3: checkSiacoins
// checkSiacoins counts the number of siacoins in the database and verifies
// that it matches the sum of all the coinbases.
func (cs *ConsensusSet) checkSiacoins() error {
// Calculate the number of expected coins in constant time.
deflationBlocks := types.InitialCoinbase - types.MinimumCoinbase
expectedSiacoins := types.CalculateCoinbase(0).Add(types.CalculateCoinbase(cs.height())).Div(types.NewCurrency64(2))
if cs.height() < types.BlockHeight(deflationBlocks) {
expectedSiacoins = expectedSiacoins.Mul(types.NewCurrency64(uint64(cs.height()) + 1))
} else {
expectedSiacoins = expectedSiacoins.Mul(types.NewCurrency64(deflationBlocks + 1))
trailingSiacoins := types.NewCurrency64(uint64(cs.height()) - deflationBlocks).Mul(types.CalculateCoinbase(cs.height()))
expectedSiacoins = expectedSiacoins.Add(trailingSiacoins)
}
totalSiacoins := types.ZeroCurrency
cs.db.forEachSiacoinOutputs(func(scoid types.SiacoinOutputID, sco types.SiacoinOutput) {
totalSiacoins = totalSiacoins.Add(sco.Value)
})
cs.db.forEachFileContracts(func(fcid types.FileContractID, fc types.FileContract) {
var payout types.Currency
for _, output := range fc.ValidProofOutputs {
payout = payout.Add(output.Value)
}
totalSiacoins = totalSiacoins.Add(payout)
})
cs.db.forEachDelayedSiacoinOutputs(func(v types.SiacoinOutputID, dso types.SiacoinOutput) {
totalSiacoins = totalSiacoins.Add(dso.Value)
})
var siafundPool types.Currency
err := cs.db.Update(func(tx *bolt.Tx) error {
siafundPool = getSiafundPool(tx)
return nil
})
if err != nil {
return err
}
cs.db.forEachSiafundOutputs(func(sfoid types.SiafundOutputID, sfo types.SiafundOutput) {
sfoSiacoins := siafundPool.Sub(sfo.ClaimStart).Div(types.SiafundCount).Mul(sfo.Value)
totalSiacoins = totalSiacoins.Add(sfoSiacoins)
})
if expectedSiacoins.Cmp(totalSiacoins) != 0 {
return errSiacoinMiscount
}
return nil
}
示例4: 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(),
//.........這裏部分代碼省略.........
示例5: FundSiafunds
// FundSiafunds will add a siafund input of exaclty 'amount' to the
// transaction. A parent transaction may be needed to achieve an input with the
// correct value. The siafund input will not be signed until 'Sign' is called
// on the transaction builder.
func (tb *transactionBuilder) FundSiafunds(amount types.Currency) error {
tb.wallet.mu.Lock()
defer tb.wallet.mu.Unlock()
// Create and fund a parent transaction that will add the correct amount of
// siafunds to the transaction.
var fund types.Currency
var potentialFund types.Currency
parentTxn := types.Transaction{}
var spentSfoids []types.SiafundOutputID
for sfoid, sfo := range tb.wallet.siafundOutputs {
// Check that this output has not recently been spent by the wallet.
spendHeight := tb.wallet.spentOutputs[types.OutputID(sfoid)]
// Prevent an underflow error.
allowedHeight := tb.wallet.consensusSetHeight - RespendTimeout
if tb.wallet.consensusSetHeight < RespendTimeout {
allowedHeight = 0
}
if spendHeight > allowedHeight {
potentialFund = potentialFund.Add(sfo.Value)
continue
}
outputUnlockConditions := tb.wallet.keys[sfo.UnlockHash].UnlockConditions
if tb.wallet.consensusSetHeight < outputUnlockConditions.Timelock {
continue
}
// Add a siafund input for this output.
parentClaimUnlockConditions, err := tb.wallet.nextPrimarySeedAddress()
if err != nil {
return err
}
sfi := types.SiafundInput{
ParentID: sfoid,
UnlockConditions: outputUnlockConditions,
ClaimUnlockHash: parentClaimUnlockConditions.UnlockHash(),
}
parentTxn.SiafundInputs = append(parentTxn.SiafundInputs, sfi)
spentSfoids = append(spentSfoids, sfoid)
// Add the output to the total fund
fund = fund.Add(sfo.Value)
potentialFund = potentialFund.Add(sfo.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.SiafundOutput{
Value: amount,
UnlockHash: parentUnlockConditions.UnlockHash(),
}
parentTxn.SiafundOutputs = append(parentTxn.SiafundOutputs, exactOutput)
// Create a refund output if needed.
if amount.Cmp(fund) != 0 {
refundUnlockConditions, err := tb.wallet.nextPrimarySeedAddress()
if err != nil {
return err
}
refundOutput := types.SiafundOutput{
Value: fund.Sub(amount),
UnlockHash: refundUnlockConditions.UnlockHash(),
}
parentTxn.SiafundOutputs = append(parentTxn.SiafundOutputs, refundOutput)
}
// Sign all of the inputs to the parent trancstion.
for _, sfi := range parentTxn.SiafundInputs {
_, err := addSignatures(&parentTxn, types.FullCoveredFields, sfi.UnlockConditions, crypto.Hash(sfi.ParentID), tb.wallet.keys[sfi.UnlockConditions.UnlockHash()])
if err != nil {
return err
}
}
// Add the exact output.
claimUnlockConditions, err := tb.wallet.nextPrimarySeedAddress()
if err != nil {
return err
}
newInput := types.SiafundInput{
ParentID: parentTxn.SiafundOutputID(0),
UnlockConditions: parentUnlockConditions,
ClaimUnlockHash: claimUnlockConditions.UnlockHash(),
//.........這裏部分代碼省略.........
示例6: FundSiafunds
// FundSiafunds will add a siafund input of exaclty 'amount' to the
// transaction. A parent transaction may be needed to achieve an input with the
// correct value. The siafund input will not be signed until 'Sign' is called
// on the transaction builder.
//
// TODO: The implementation of FundSiacoins is known to have quirks/bugs
// (non-fatal), and has diverged from the implementation of FundSiacoins. The
// implementations should be converged once again.
func (tb *transactionBuilder) FundSiafunds(amount types.Currency) error {
lockID := tb.wallet.mu.Lock()
defer tb.wallet.mu.Unlock(lockID)
// Create and fund a parent transaction that will add the correct amount of
// siafunds to the transaction.
var fund types.Currency
parentTxn := types.Transaction{}
for scoid, sco := range tb.wallet.siafundOutputs {
// Check that this output has not recently been spent by the wallet.
spendHeight := tb.wallet.spentOutputs[types.OutputID(scoid)]
if spendHeight > tb.wallet.consensusSetHeight-RespendTimeout {
continue
}
outputUnlockConditions := tb.wallet.keys[sco.UnlockHash].unlockConditions
if tb.wallet.consensusSetHeight < outputUnlockConditions.Timelock {
continue
}
// Mark the output as spent.
tb.wallet.spentOutputs[types.OutputID(scoid)] = tb.wallet.consensusSetHeight
// Add a siafund input for this output.
parentClaimUnlockConditions, err := tb.wallet.nextPrimarySeedAddress()
if err != nil {
return err
}
sci := types.SiafundInput{
ParentID: scoid,
UnlockConditions: outputUnlockConditions,
ClaimUnlockHash: parentClaimUnlockConditions.UnlockHash(),
}
parentTxn.SiafundInputs = append(parentTxn.SiafundInputs, sci)
// Add the output to the total fund
fund = fund.Add(sco.Value)
if fund.Cmp(amount) >= 0 {
break
}
}
// 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.SiafundOutput{
Value: amount,
UnlockHash: parentUnlockConditions.UnlockHash(),
}
parentTxn.SiafundOutputs = append(parentTxn.SiafundOutputs, exactOutput)
// Create a refund output if needed.
if amount.Cmp(fund) != 0 {
refundUnlockConditions, err := tb.wallet.nextPrimarySeedAddress()
if err != nil {
return err
}
refundOutput := types.SiafundOutput{
Value: fund.Sub(amount),
UnlockHash: refundUnlockConditions.UnlockHash(),
}
parentTxn.SiafundOutputs = append(parentTxn.SiafundOutputs, refundOutput)
}
// Sign all of the inputs to the parent trancstion.
for _, sfi := range parentTxn.SiafundInputs {
err := addSignatures(&parentTxn, types.FullCoveredFields, sfi.UnlockConditions, crypto.Hash(sfi.ParentID), tb.wallet.keys[sfi.UnlockConditions.UnlockHash()])
if err != nil {
return err
}
}
// Add the exact output.
claimUnlockConditions, err := tb.wallet.nextPrimarySeedAddress()
if err != nil {
return err
}
newInput := types.SiafundInput{
ParentID: parentTxn.SiafundOutputID(0),
UnlockConditions: parentUnlockConditions,
ClaimUnlockHash: claimUnlockConditions.UnlockHash(),
}
tb.parents = append(tb.parents, parentTxn)
tb.siafundInputs = append(tb.siafundInputs, len(tb.transaction.SiafundInputs))
tb.transaction.SiafundInputs = append(tb.transaction.SiafundInputs, newInput)
return nil
}
示例7: SendSiagSiafunds
//.........這裏部分代碼省略.........
return types.Transaction{}, ErrInsufficientSiafunds
}
// Truncate the keys to exactly the number needed.
skps = skps[:skps[0].UnlockConditions.SignaturesRequired]
// Assemble the base transction, including a 10 siacoin fee if possible.
id, err := w.RegisterTransaction(types.Transaction{})
if err != nil {
return types.Transaction{}, err
}
// Add a miner fee - if funding the transaction fails, we'll just send a
// transaction with no fee.
txn, err := w.FundTransaction(id, types.NewCurrency64(TransactionFee))
if err == nil {
txn, _, err = w.AddMinerFee(id, types.NewCurrency64(TransactionFee))
if err != nil {
return types.Transaction{}, err
}
}
// Add the siafund inputs to the transcation.
for _, sfoid := range sfoids {
// Get an address for the siafund claims.
lockID := w.mu.Lock()
claimDest, _, err := w.coinAddress(false)
w.mu.Unlock(lockID)
if err != nil {
return types.Transaction{}, err
}
// Assemble the SiafundInput to spend this output.
sfi := types.SiafundInput{
ParentID: sfoid,
UnlockConditions: skps[0].UnlockConditions,
ClaimUnlockHash: claimDest,
}
txn, _, err = w.AddSiafundInput(id, sfi)
if err != nil {
return types.Transaction{}, err
}
}
// Add the siafund output to the transaction.
sfo := types.SiafundOutput{
Value: amount,
UnlockHash: dest,
}
txn, _, err = w.AddSiafundOutput(id, sfo)
if err != nil {
return types.Transaction{}, err
}
// Add a refund siafund output if needed.
if amount.Cmp(availableSiafunds) != 0 {
refund := availableSiafunds.Sub(amount)
sfo := types.SiafundOutput{
Value: refund,
UnlockHash: baseUnlockHash,
}
txn, _, err = w.AddSiafundOutput(id, sfo)
if err != nil {
return types.Transaction{}, err
}
}
// Add signatures for the siafund inputs.
sigIndex := 0
for _, sfoid := range sfoids {
for _, key := range skps {
txnSig := types.TransactionSignature{
ParentID: crypto.Hash(sfoid),
CoveredFields: types.CoveredFields{WholeTransaction: true},
PublicKeyIndex: uint64(key.Index),
}
txn.TransactionSignatures = append(txn.TransactionSignatures, txnSig)
sigHash := txn.SigHash(sigIndex)
encodedSig, err := crypto.SignHash(sigHash, key.SecretKey)
if err != nil {
return types.Transaction{}, err
}
txn.TransactionSignatures[sigIndex].Signature = encodedSig[:]
txn, _, err = w.AddTransactionSignature(id, txn.TransactionSignatures[sigIndex])
if err != nil {
return types.Transaction{}, err
}
sigIndex++
}
}
// Sign the transaction.
txn, err = w.SignTransaction(id, true)
if err != nil {
return types.Transaction{}, err
}
err = w.tpool.AcceptTransaction(txn)
if err != nil {
return types.Transaction{}, err
}
return txn, nil
}