forked from TrueCloudLab/neoneo-go
core: export UtilityTokenID and GoverningTokenID
Both are very useful outside of the core, this change also makes respective transactions initialize with the package as they don't depend on any kind of input and it makes no sense recreating them again and again on every use.
This commit is contained in:
parent
b41a5239c6
commit
a4294f4b5f
4 changed files with 42 additions and 33 deletions
|
@ -432,7 +432,7 @@ func (bc *Blockchain) storeBlock(block *block.Block) error {
|
|||
return err
|
||||
}
|
||||
|
||||
if prevTXOutput.AssetID.Equals(governingTokenTX().Hash()) {
|
||||
if prevTXOutput.AssetID.Equals(GoverningTokenID()) {
|
||||
spentCoin := NewSpentCoinState(input.PrevHash, prevTXHeight)
|
||||
spentCoin.items[input.PrevIndex] = block.Index
|
||||
if err = cache.PutSpentCoinState(input.PrevHash, spentCoin); err != nil {
|
||||
|
@ -648,14 +648,14 @@ func processOutputs(tx *transaction.Transaction, dao *cachedDao) error {
|
|||
}
|
||||
|
||||
func processTXWithValidatorsAdd(output *transaction.Output, account *state.Account, dao *cachedDao) error {
|
||||
if output.AssetID.Equals(governingTokenTX().Hash()) && len(account.Votes) > 0 {
|
||||
if output.AssetID.Equals(GoverningTokenID()) && len(account.Votes) > 0 {
|
||||
return modAccountVotes(account, dao, output.Amount)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func processTXWithValidatorsSubtract(output *transaction.Output, account *state.Account, dao *cachedDao) error {
|
||||
if output.AssetID.Equals(governingTokenTX().Hash()) && len(account.Votes) > 0 {
|
||||
if output.AssetID.Equals(GoverningTokenID()) && len(account.Votes) > 0 {
|
||||
return modAccountVotes(account, dao, -output.Amount)
|
||||
}
|
||||
return nil
|
||||
|
@ -724,7 +724,7 @@ func processAccountStateDescriptor(descriptor *transaction.StateDescriptor, dao
|
|||
}
|
||||
|
||||
if descriptor.Field == "Votes" {
|
||||
balance := account.GetBalanceValues()[governingTokenTX().Hash()]
|
||||
balance := account.GetBalanceValues()[GoverningTokenID()]
|
||||
if err = modAccountVotes(account, dao, -balance); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -999,14 +999,14 @@ func (bc *Blockchain) FeePerByte(t *transaction.Transaction) util.Fixed8 {
|
|||
func (bc *Blockchain) NetworkFee(t *transaction.Transaction) util.Fixed8 {
|
||||
inputAmount := util.Fixed8FromInt64(0)
|
||||
for _, txOutput := range bc.References(t) {
|
||||
if txOutput.AssetID == utilityTokenTX().Hash() {
|
||||
if txOutput.AssetID == UtilityTokenID() {
|
||||
inputAmount.Add(txOutput.Amount)
|
||||
}
|
||||
}
|
||||
|
||||
outputAmount := util.Fixed8FromInt64(0)
|
||||
for _, txOutput := range t.Outputs {
|
||||
if txOutput.AssetID == utilityTokenTX().Hash() {
|
||||
if txOutput.AssetID == UtilityTokenID() {
|
||||
outputAmount.Add(txOutput.Amount)
|
||||
}
|
||||
}
|
||||
|
@ -1192,7 +1192,7 @@ func (bc *Blockchain) verifyResults(t *transaction.Transaction) error {
|
|||
if len(resultsDestroy) > 1 {
|
||||
return errors.New("tx has more than 1 destroy output")
|
||||
}
|
||||
if len(resultsDestroy) == 1 && resultsDestroy[0].AssetID != utilityTokenTX().Hash() {
|
||||
if len(resultsDestroy) == 1 && resultsDestroy[0].AssetID != UtilityTokenID() {
|
||||
return errors.New("tx destroys non-utility token")
|
||||
}
|
||||
sysfee := bc.SystemFee(t)
|
||||
|
@ -1208,14 +1208,14 @@ func (bc *Blockchain) verifyResults(t *transaction.Transaction) error {
|
|||
switch t.Type {
|
||||
case transaction.MinerType, transaction.ClaimType:
|
||||
for _, r := range resultsIssue {
|
||||
if r.AssetID != utilityTokenTX().Hash() {
|
||||
if r.AssetID != UtilityTokenID() {
|
||||
return errors.New("miner or claim tx issues non-utility tokens")
|
||||
}
|
||||
}
|
||||
break
|
||||
case transaction.IssueType:
|
||||
for _, r := range resultsIssue {
|
||||
if r.AssetID == utilityTokenTX().Hash() {
|
||||
if r.AssetID == UtilityTokenID() {
|
||||
return errors.New("issue tx issues utility tokens")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,17 @@ import (
|
|||
"github.com/CityOfZion/neo-go/pkg/vm/opcode"
|
||||
)
|
||||
|
||||
var (
|
||||
// governingTokenTX represents transaction that is used to create
|
||||
// governing (NEO) token. It's a part of the genesis block.
|
||||
governingTokenTX transaction.Transaction
|
||||
|
||||
// utilityTokenTX represents transaction that is used to create
|
||||
// utility (GAS) token. It's a part of the genesis block. It's mostly
|
||||
// useful for its hash that represents GAS asset ID.
|
||||
utilityTokenTX transaction.Transaction
|
||||
)
|
||||
|
||||
// createGenesisBlock creates a genesis block based on the given configuration.
|
||||
func createGenesisBlock(cfg config.ProtocolConfiguration) (*block.Block, error) {
|
||||
validators, err := getValidators(cfg)
|
||||
|
@ -38,8 +49,6 @@ func createGenesisBlock(cfg config.ProtocolConfiguration) (*block.Block, error)
|
|||
},
|
||||
}
|
||||
|
||||
governingTX := governingTokenTX()
|
||||
utilityTX := utilityTokenTX()
|
||||
rawScript, err := smartcontract.CreateMultiSigRedeemScript(
|
||||
len(cfg.StandbyValidators)/2+1,
|
||||
validators,
|
||||
|
@ -62,16 +71,16 @@ func createGenesisBlock(cfg config.ProtocolConfiguration) (*block.Block, error)
|
|||
Outputs: []transaction.Output{},
|
||||
Scripts: []transaction.Witness{},
|
||||
},
|
||||
governingTX,
|
||||
utilityTX,
|
||||
&governingTokenTX,
|
||||
&utilityTokenTX,
|
||||
{
|
||||
Type: transaction.IssueType,
|
||||
Data: &transaction.IssueTX{}, // no fields.
|
||||
Inputs: []transaction.Input{},
|
||||
Outputs: []transaction.Output{
|
||||
{
|
||||
AssetID: governingTX.Hash(),
|
||||
Amount: governingTX.Data.(*transaction.RegisterTX).Amount,
|
||||
AssetID: governingTokenTX.Hash(),
|
||||
Amount: governingTokenTX.Data.(*transaction.RegisterTX).Amount,
|
||||
ScriptHash: scriptOut,
|
||||
},
|
||||
},
|
||||
|
@ -92,7 +101,7 @@ func createGenesisBlock(cfg config.ProtocolConfiguration) (*block.Block, error)
|
|||
return b, nil
|
||||
}
|
||||
|
||||
func governingTokenTX() *transaction.Transaction {
|
||||
func init() {
|
||||
admin := hash.Hash160([]byte{byte(opcode.PUSHT)})
|
||||
registerTX := &transaction.RegisterTX{
|
||||
AssetType: transaction.GoverningToken,
|
||||
|
@ -102,7 +111,7 @@ func governingTokenTX() *transaction.Transaction {
|
|||
Admin: admin,
|
||||
}
|
||||
|
||||
tx := &transaction.Transaction{
|
||||
governingTokenTX = transaction.Transaction{
|
||||
Type: transaction.RegisterType,
|
||||
Data: registerTX,
|
||||
Attributes: []transaction.Attribute{},
|
||||
|
@ -111,19 +120,15 @@ func governingTokenTX() *transaction.Transaction {
|
|||
Scripts: []transaction.Witness{},
|
||||
}
|
||||
|
||||
return tx
|
||||
}
|
||||
|
||||
func utilityTokenTX() *transaction.Transaction {
|
||||
admin := hash.Hash160([]byte{byte(opcode.PUSHF)})
|
||||
registerTX := &transaction.RegisterTX{
|
||||
admin = hash.Hash160([]byte{byte(opcode.PUSHF)})
|
||||
registerTX = &transaction.RegisterTX{
|
||||
AssetType: transaction.UtilityToken,
|
||||
Name: "[{\"lang\":\"zh-CN\",\"name\":\"小蚁币\"},{\"lang\":\"en\",\"name\":\"AntCoin\"}]",
|
||||
Amount: calculateUtilityAmount(),
|
||||
Precision: 8,
|
||||
Admin: admin,
|
||||
}
|
||||
tx := &transaction.Transaction{
|
||||
utilityTokenTX = transaction.Transaction{
|
||||
Type: transaction.RegisterType,
|
||||
Data: registerTX,
|
||||
Attributes: []transaction.Attribute{},
|
||||
|
@ -131,8 +136,16 @@ func utilityTokenTX() *transaction.Transaction {
|
|||
Outputs: []transaction.Output{},
|
||||
Scripts: []transaction.Witness{},
|
||||
}
|
||||
}
|
||||
|
||||
return tx
|
||||
// GoverningTokenID returns the governing token (NEO) hash.
|
||||
func GoverningTokenID() util.Uint256 {
|
||||
return governingTokenTX.Hash()
|
||||
}
|
||||
|
||||
// UtilityTokenID returns the utility token (GAS) hash.
|
||||
func UtilityTokenID() util.Uint256 {
|
||||
return utilityTokenTX.Hash()
|
||||
}
|
||||
|
||||
func getValidators(cfg config.ProtocolConfiguration) ([]*keys.PublicKey, error) {
|
||||
|
|
|
@ -50,12 +50,10 @@ func TestGetConsensusAddressMainNet(t *testing.T) {
|
|||
|
||||
func TestUtilityTokenTX(t *testing.T) {
|
||||
expect := "602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7"
|
||||
tx := utilityTokenTX()
|
||||
assert.Equal(t, expect, tx.Hash().StringLE())
|
||||
assert.Equal(t, expect, UtilityTokenID().StringLE())
|
||||
}
|
||||
|
||||
func TestGoverningTokenTX(t *testing.T) {
|
||||
expect := "c56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b"
|
||||
tx := governingTokenTX()
|
||||
assert.Equal(t, expect, tx.Hash().StringLE())
|
||||
assert.Equal(t, expect, GoverningTokenID().StringLE())
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"encoding/hex"
|
||||
"fmt"
|
||||
|
||||
"github.com/CityOfZion/neo-go/pkg/core"
|
||||
"github.com/CityOfZion/neo-go/pkg/core/transaction"
|
||||
"github.com/CityOfZion/neo-go/pkg/crypto/keys"
|
||||
"github.com/CityOfZion/neo-go/pkg/smartcontract"
|
||||
|
@ -160,15 +161,12 @@ func (c *Client) SignAndPushInvocationTx(script []byte, wif *keys.WIF, gas util.
|
|||
var txHash util.Uint256
|
||||
var err error
|
||||
|
||||
gasIDB, _ := hex.DecodeString("602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7")
|
||||
gasID, _ := util.Uint256DecodeBytesLE(gasIDB)
|
||||
|
||||
tx := transaction.NewInvocationTX(script, gas)
|
||||
|
||||
fromAddress := wif.PrivateKey.Address()
|
||||
|
||||
if gas > 0 {
|
||||
if err = AddInputsAndUnspentsToTx(tx, fromAddress, gasID, gas, c); err != nil {
|
||||
if err = AddInputsAndUnspentsToTx(tx, fromAddress, core.UtilityTokenID(), gas, c); err != nil {
|
||||
return txHash, errors.Wrap(err, "failed to add inputs and unspents to transaction")
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue