2018-03-09 15:55:25 +00:00
|
|
|
package core
|
|
|
|
|
2018-03-17 11:53:21 +00:00
|
|
|
import (
|
2023-10-19 12:29:41 +00:00
|
|
|
"fmt"
|
2018-03-25 10:45:54 +00:00
|
|
|
"time"
|
2018-03-17 11:53:21 +00:00
|
|
|
|
2020-03-25 15:30:21 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/config"
|
2020-03-03 14:21:42 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
2018-03-17 11:53:21 +00:00
|
|
|
)
|
2018-03-09 15:55:25 +00:00
|
|
|
|
2022-06-08 15:20:34 +00:00
|
|
|
// CreateGenesisBlock creates a genesis block based on the given configuration.
|
|
|
|
func CreateGenesisBlock(cfg config.ProtocolConfiguration) (*block.Block, error) {
|
2023-10-19 12:29:41 +00:00
|
|
|
validators, committee, err := validatorsFromConfig(cfg)
|
2018-03-25 10:45:54 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
nextConsensus, err := getNextConsensusAddress(validators)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2023-10-19 12:29:41 +00:00
|
|
|
txs := []*transaction.Transaction{}
|
|
|
|
if cfg.Genesis.Transaction != nil {
|
|
|
|
committeeH, err := getCommitteeAddress(committee)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("failed to calculate committee address: %w", err)
|
|
|
|
}
|
|
|
|
tx := cfg.Genesis.Transaction
|
|
|
|
signers := []transaction.Signer{
|
|
|
|
{
|
|
|
|
Account: nextConsensus,
|
|
|
|
Scopes: transaction.CalledByEntry,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
scripts := []transaction.Witness{
|
|
|
|
{
|
|
|
|
InvocationScript: []byte{},
|
|
|
|
VerificationScript: []byte{byte(opcode.PUSH1)},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
if !committeeH.Equals(nextConsensus) {
|
|
|
|
signers = append(signers, []transaction.Signer{
|
|
|
|
{
|
|
|
|
Account: committeeH,
|
|
|
|
Scopes: transaction.CalledByEntry,
|
|
|
|
},
|
|
|
|
}...)
|
|
|
|
scripts = append(scripts, []transaction.Witness{
|
|
|
|
{
|
|
|
|
InvocationScript: []byte{},
|
|
|
|
VerificationScript: []byte{byte(opcode.PUSH1)},
|
|
|
|
},
|
|
|
|
}...)
|
|
|
|
}
|
|
|
|
|
|
|
|
txs = append(txs, &transaction.Transaction{
|
|
|
|
SystemFee: tx.SystemFee,
|
|
|
|
ValidUntilBlock: 1,
|
|
|
|
Script: tx.Script,
|
|
|
|
Signers: signers,
|
|
|
|
Scripts: scripts,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-03-01 13:44:47 +00:00
|
|
|
base := block.Header{
|
2018-03-25 10:45:54 +00:00
|
|
|
Version: 0,
|
|
|
|
PrevHash: util.Uint256{},
|
2020-06-05 10:05:50 +00:00
|
|
|
Timestamp: uint64(time.Date(2016, 7, 15, 15, 8, 21, 0, time.UTC).Unix()) * 1000, // Milliseconds.
|
2021-07-14 08:32:54 +00:00
|
|
|
Nonce: 2083236893,
|
2018-03-25 10:45:54 +00:00
|
|
|
Index: 0,
|
|
|
|
NextConsensus: nextConsensus,
|
2019-12-09 14:14:10 +00:00
|
|
|
Script: transaction.Witness{
|
2018-03-25 10:45:54 +00:00
|
|
|
InvocationScript: []byte{},
|
2020-06-05 10:04:20 +00:00
|
|
|
VerificationScript: []byte{byte(opcode.PUSH1)},
|
2018-03-25 10:45:54 +00:00
|
|
|
},
|
2020-11-23 13:24:47 +00:00
|
|
|
StateRootEnabled: cfg.StateRootInHeader,
|
2018-03-25 10:45:54 +00:00
|
|
|
}
|
|
|
|
|
2020-01-14 12:32:07 +00:00
|
|
|
b := &block.Block{
|
2021-03-01 13:44:47 +00:00
|
|
|
Header: base,
|
2023-10-19 12:29:41 +00:00
|
|
|
Transactions: txs,
|
2018-03-25 10:45:54 +00:00
|
|
|
}
|
2020-09-15 15:38:15 +00:00
|
|
|
b.RebuildMerkleRoot()
|
2018-03-25 10:45:54 +00:00
|
|
|
|
2020-01-14 12:32:07 +00:00
|
|
|
return b, nil
|
2018-03-25 10:45:54 +00:00
|
|
|
}
|
|
|
|
|
2023-10-19 12:29:41 +00:00
|
|
|
func validatorsFromConfig(cfg config.ProtocolConfiguration) ([]*keys.PublicKey, []*keys.PublicKey, error) {
|
2022-01-24 15:36:31 +00:00
|
|
|
vs, err := keys.NewPublicKeysFromStrings(cfg.StandbyCommittee)
|
2020-08-05 08:30:14 +00:00
|
|
|
if err != nil {
|
2023-10-19 12:29:41 +00:00
|
|
|
return nil, nil, err
|
2020-08-05 08:30:14 +00:00
|
|
|
}
|
2023-10-19 12:29:41 +00:00
|
|
|
return vs.Copy()[:cfg.GetNumOfCNs(0)], vs, nil
|
2020-08-05 08:30:14 +00:00
|
|
|
}
|
|
|
|
|
2019-08-27 13:29:42 +00:00
|
|
|
func getNextConsensusAddress(validators []*keys.PublicKey) (val util.Uint160, err error) {
|
2020-08-10 15:58:11 +00:00
|
|
|
raw, err := smartcontract.CreateDefaultMultiSigRedeemScript(validators)
|
2018-03-25 10:45:54 +00:00
|
|
|
if err != nil {
|
|
|
|
return val, err
|
|
|
|
}
|
2019-08-23 15:50:45 +00:00
|
|
|
return hash.Hash160(raw), nil
|
2018-03-25 10:45:54 +00:00
|
|
|
}
|
|
|
|
|
2023-10-19 12:29:41 +00:00
|
|
|
func getCommitteeAddress(committee []*keys.PublicKey) (val util.Uint160, err error) {
|
|
|
|
raw, err := smartcontract.CreateMajorityMultiSigRedeemScript(committee)
|
|
|
|
if err != nil {
|
|
|
|
return val, err
|
|
|
|
}
|
|
|
|
return hash.Hash160(raw), nil
|
|
|
|
}
|