diff --git a/pkg/core/blockchain.go b/pkg/core/blockchain.go index 9d712f16a..1c3869c89 100644 --- a/pkg/core/blockchain.go +++ b/pkg/core/blockchain.go @@ -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") } } diff --git a/pkg/core/util.go b/pkg/core/util.go index 4465a0621..77fcddc22 100644 --- a/pkg/core/util.go +++ b/pkg/core/util.go @@ -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) { diff --git a/pkg/core/util_test.go b/pkg/core/util_test.go index b2222a56a..aaa39ae63 100644 --- a/pkg/core/util_test.go +++ b/pkg/core/util_test.go @@ -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()) } diff --git a/pkg/rpc/rpc.go b/pkg/rpc/rpc.go index 9beaad3d3..8ba1af6c5 100644 --- a/pkg/rpc/rpc.go +++ b/pkg/rpc/rpc.go @@ -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") } }