mirror of https://github.com/poanetwork/gecko.git
Implemented NFTs
This commit is contained in:
parent
ffcdfafaf6
commit
a2c0ad56f7
|
@ -8,19 +8,28 @@ package genesis
|
|||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"math/big"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/ava-labs/coreth/core"
|
||||
"github.com/ava-labs/gecko/ids"
|
||||
"github.com/ava-labs/gecko/utils/formatting"
|
||||
"github.com/ava-labs/gecko/utils/json"
|
||||
"github.com/ava-labs/gecko/utils/units"
|
||||
"github.com/ava-labs/gecko/vms/avm"
|
||||
"github.com/ava-labs/gecko/vms/components/codec"
|
||||
"github.com/ava-labs/gecko/vms/evm"
|
||||
"github.com/ava-labs/gecko/vms/nftfx"
|
||||
"github.com/ava-labs/gecko/vms/platformvm"
|
||||
"github.com/ava-labs/gecko/vms/secp256k1fx"
|
||||
"github.com/ava-labs/gecko/vms/spchainvm"
|
||||
"github.com/ava-labs/gecko/vms/spdagvm"
|
||||
"github.com/ava-labs/gecko/vms/timestampvm"
|
||||
"github.com/ava-labs/go-ethereum/common"
|
||||
"github.com/ava-labs/go-ethereum/params"
|
||||
)
|
||||
|
||||
// Note that since an AVA network has exactly one Platform Chain,
|
||||
|
@ -149,6 +158,8 @@ func Aliases(networkID uint32) (generalAliases map[string][]string, chainAliases
|
|||
spdagvm.ID.Key(): []string{"spdag"},
|
||||
spchainvm.ID.Key(): []string{"spchain"},
|
||||
timestampvm.ID.Key(): []string{"timestamp"},
|
||||
secp256k1fx.ID.Key(): []string{"secp256k1fx"},
|
||||
nftfx.ID.Key(): []string{"nftfx"},
|
||||
}
|
||||
|
||||
genesisBytes := Genesis(networkID)
|
||||
|
@ -187,318 +198,195 @@ func Genesis(networkID uint32) []byte {
|
|||
panic("unknown network ID provided")
|
||||
}
|
||||
|
||||
return []byte{
|
||||
0x00, 0x00, 0x00, 0x01, 0x3c, 0xb7, 0xd3, 0x84,
|
||||
0x2e, 0x8c, 0xee, 0x6a, 0x0e, 0xbd, 0x09, 0xf1,
|
||||
0xfe, 0x88, 0x4f, 0x68, 0x61, 0xe1, 0xb2, 0x9c,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x12, 0x30, 0x9c, 0xe5, 0x40, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
|
||||
0x0b, 0xde, 0x31, 0xb4, 0xd8, 0xb2, 0x29, 0x91,
|
||||
0xd5, 0x1a, 0xa6, 0xaa, 0x1f, 0xc7, 0x33, 0xf2,
|
||||
0x3a, 0x85, 0x1a, 0x8c, 0x94, 0x00, 0x00, 0x12,
|
||||
0x30, 0x9c, 0xe5, 0x40, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x5d, 0xbb, 0x75, 0x80, 0x00, 0x00, 0x00,
|
||||
0x00, 0x5f, 0x9c, 0xa9, 0x00, 0x00, 0x00, 0x30,
|
||||
0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x3c, 0xb7, 0xd3, 0x84, 0x2e, 0x8c, 0xee,
|
||||
0x6a, 0x0e, 0xbd, 0x09, 0xf1, 0xfe, 0x88, 0x4f,
|
||||
0x68, 0x61, 0xe1, 0xb2, 0x9c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xaa, 0x18,
|
||||
0xd3, 0x99, 0x1c, 0xf6, 0x37, 0xaa, 0x6c, 0x16,
|
||||
0x2f, 0x5e, 0x95, 0xcf, 0x16, 0x3f, 0x69, 0xcd,
|
||||
0x82, 0x91, 0x00, 0x00, 0x12, 0x30, 0x9c, 0xe5,
|
||||
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, 0xbb,
|
||||
0x75, 0x80, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x9c,
|
||||
0xa9, 0x00, 0x00, 0x00, 0x30, 0x39, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0xb7,
|
||||
0xd3, 0x84, 0x2e, 0x8c, 0xee, 0x6a, 0x0e, 0xbd,
|
||||
0x09, 0xf1, 0xfe, 0x88, 0x4f, 0x68, 0x61, 0xe1,
|
||||
0xb2, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x0b, 0xe9, 0x09, 0x4f, 0x73, 0x69,
|
||||
0x80, 0x02, 0xfd, 0x52, 0xc9, 0x08, 0x19, 0xb4,
|
||||
0x57, 0xb9, 0xfb, 0xc8, 0x66, 0xab, 0x80, 0x00,
|
||||
0x00, 0x12, 0x30, 0x9c, 0xe5, 0x40, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x5d, 0xbb, 0x75, 0x80, 0x00,
|
||||
0x00, 0x00, 0x00, 0x5f, 0x9c, 0xa9, 0x00, 0x00,
|
||||
0x00, 0x30, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x3c, 0xb7, 0xd3, 0x84, 0x2e,
|
||||
0x8c, 0xee, 0x6a, 0x0e, 0xbd, 0x09, 0xf1, 0xfe,
|
||||
0x88, 0x4f, 0x68, 0x61, 0xe1, 0xb2, 0x9c, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b,
|
||||
0x47, 0x9f, 0x66, 0xc8, 0xbe, 0x89, 0x58, 0x30,
|
||||
0x54, 0x7e, 0x70, 0xb4, 0xb2, 0x98, 0xca, 0xfd,
|
||||
0x43, 0x3d, 0xba, 0x6e, 0x00, 0x00, 0x12, 0x30,
|
||||
0x9c, 0xe5, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x5d, 0xbb, 0x75, 0x80, 0x00, 0x00, 0x00, 0x00,
|
||||
0x5f, 0x9c, 0xa9, 0x00, 0x00, 0x00, 0x30, 0x39,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x3c, 0xb7, 0xd3, 0x84, 0x2e, 0x8c, 0xee, 0x6a,
|
||||
0x0e, 0xbd, 0x09, 0xf1, 0xfe, 0x88, 0x4f, 0x68,
|
||||
0x61, 0xe1, 0xb2, 0x9c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x0b, 0xf2, 0x9b, 0xce,
|
||||
0x5f, 0x34, 0xa7, 0x43, 0x01, 0xeb, 0x0d, 0xe7,
|
||||
0x16, 0xd5, 0x19, 0x4e, 0x4a, 0x4a, 0xea, 0x5d,
|
||||
0x7a, 0x00, 0x00, 0x12, 0x30, 0x9c, 0xe5, 0x40,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, 0xbb, 0x75,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x9c, 0xa9,
|
||||
0x00, 0x00, 0x00, 0x30, 0x39, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0xb7, 0xd3,
|
||||
0x84, 0x2e, 0x8c, 0xee, 0x6a, 0x0e, 0xbd, 0x09,
|
||||
0xf1, 0xfe, 0x88, 0x4f, 0x68, 0x61, 0xe1, 0xb2,
|
||||
0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x05, 0x00, 0x00, 0x30, 0x39, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
|
||||
0x58, 0x2d, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x61,
|
||||
0x76, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x73, 0x65, 0x63, 0x70, 0x32,
|
||||
0x35, 0x36, 0x6b, 0x31, 0x66, 0x78, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x03, 0x41, 0x56, 0x41,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x41, 0x56,
|
||||
0x41, 0x00, 0x03, 0x41, 0x56, 0x41, 0x09, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00,
|
||||
0x9f, 0xdf, 0x42, 0xf6, 0xe4, 0x80, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x3c,
|
||||
0xb7, 0xd3, 0x84, 0x2e, 0x8c, 0xee, 0x6a, 0x0e,
|
||||
0xbd, 0x09, 0xf1, 0xfe, 0x88, 0x4f, 0x68, 0x61,
|
||||
0xe1, 0xb2, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x39,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x07, 0x43, 0x2d, 0x43, 0x68, 0x61, 0x69,
|
||||
0x6e, 0x65, 0x76, 0x6d, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
|
||||
0xc9, 0x7b, 0x22, 0x63, 0x6f, 0x6e, 0x66, 0x69,
|
||||
0x67, 0x22, 0x3a, 0x7b, 0x22, 0x63, 0x68, 0x61,
|
||||
0x69, 0x6e, 0x49, 0x64, 0x22, 0x3a, 0x34, 0x33,
|
||||
0x31, 0x31, 0x30, 0x2c, 0x22, 0x68, 0x6f, 0x6d,
|
||||
0x65, 0x73, 0x74, 0x65, 0x61, 0x64, 0x42, 0x6c,
|
||||
0x6f, 0x63, 0x6b, 0x22, 0x3a, 0x30, 0x2c, 0x22,
|
||||
0x64, 0x61, 0x6f, 0x46, 0x6f, 0x72, 0x6b, 0x42,
|
||||
0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x3a, 0x30, 0x2c,
|
||||
0x22, 0x64, 0x61, 0x6f, 0x46, 0x6f, 0x72, 0x6b,
|
||||
0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x22,
|
||||
0x3a, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x22, 0x65,
|
||||
0x69, 0x70, 0x31, 0x35, 0x30, 0x42, 0x6c, 0x6f,
|
||||
0x63, 0x6b, 0x22, 0x3a, 0x30, 0x2c, 0x22, 0x65,
|
||||
0x69, 0x70, 0x31, 0x35, 0x30, 0x48, 0x61, 0x73,
|
||||
0x68, 0x22, 0x3a, 0x22, 0x30, 0x78, 0x32, 0x30,
|
||||
0x38, 0x36, 0x37, 0x39, 0x39, 0x61, 0x65, 0x65,
|
||||
0x62, 0x65, 0x61, 0x65, 0x31, 0x33, 0x35, 0x63,
|
||||
0x32, 0x34, 0x36, 0x63, 0x36, 0x35, 0x30, 0x32,
|
||||
0x31, 0x63, 0x38, 0x32, 0x62, 0x34, 0x65, 0x31,
|
||||
0x35, 0x61, 0x32, 0x63, 0x34, 0x35, 0x31, 0x33,
|
||||
0x34, 0x30, 0x39, 0x39, 0x33, 0x61, 0x61, 0x63,
|
||||
0x66, 0x64, 0x32, 0x37, 0x35, 0x31, 0x38, 0x38,
|
||||
0x36, 0x35, 0x31, 0x34, 0x66, 0x30, 0x22, 0x2c,
|
||||
0x22, 0x65, 0x69, 0x70, 0x31, 0x35, 0x35, 0x42,
|
||||
0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x3a, 0x30, 0x2c,
|
||||
0x22, 0x65, 0x69, 0x70, 0x31, 0x35, 0x38, 0x42,
|
||||
0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x3a, 0x30, 0x2c,
|
||||
0x22, 0x62, 0x79, 0x7a, 0x61, 0x6e, 0x74, 0x69,
|
||||
0x75, 0x6d, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x22,
|
||||
0x3a, 0x30, 0x2c, 0x22, 0x63, 0x6f, 0x6e, 0x73,
|
||||
0x74, 0x61, 0x6e, 0x74, 0x69, 0x6e, 0x6f, 0x70,
|
||||
0x6c, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x22,
|
||||
0x3a, 0x30, 0x2c, 0x22, 0x70, 0x65, 0x74, 0x65,
|
||||
0x72, 0x73, 0x62, 0x75, 0x72, 0x67, 0x42, 0x6c,
|
||||
0x6f, 0x63, 0x6b, 0x22, 0x3a, 0x30, 0x7d, 0x2c,
|
||||
0x22, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x22, 0x3a,
|
||||
0x22, 0x30, 0x78, 0x30, 0x22, 0x2c, 0x22, 0x74,
|
||||
0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
|
||||
0x22, 0x3a, 0x22, 0x30, 0x78, 0x30, 0x22, 0x2c,
|
||||
0x22, 0x65, 0x78, 0x74, 0x72, 0x61, 0x44, 0x61,
|
||||
0x74, 0x61, 0x22, 0x3a, 0x22, 0x30, 0x78, 0x30,
|
||||
0x30, 0x22, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x4c,
|
||||
0x69, 0x6d, 0x69, 0x74, 0x22, 0x3a, 0x22, 0x30,
|
||||
0x78, 0x35, 0x66, 0x35, 0x65, 0x31, 0x30, 0x30,
|
||||
0x22, 0x2c, 0x22, 0x64, 0x69, 0x66, 0x66, 0x69,
|
||||
0x63, 0x75, 0x6c, 0x74, 0x79, 0x22, 0x3a, 0x22,
|
||||
0x30, 0x78, 0x30, 0x22, 0x2c, 0x22, 0x6d, 0x69,
|
||||
0x78, 0x48, 0x61, 0x73, 0x68, 0x22, 0x3a, 0x22,
|
||||
0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x22, 0x2c, 0x22, 0x63, 0x6f, 0x69,
|
||||
0x6e, 0x62, 0x61, 0x73, 0x65, 0x22, 0x3a, 0x22,
|
||||
0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x22, 0x2c, 0x22, 0x61, 0x6c, 0x6c,
|
||||
0x6f, 0x63, 0x22, 0x3a, 0x7b, 0x22, 0x37, 0x35,
|
||||
0x31, 0x61, 0x30, 0x62, 0x39, 0x36, 0x65, 0x31,
|
||||
0x30, 0x34, 0x32, 0x62, 0x65, 0x65, 0x37, 0x38,
|
||||
0x39, 0x34, 0x35, 0x32, 0x65, 0x63, 0x62, 0x32,
|
||||
0x30, 0x32, 0x35, 0x33, 0x66, 0x62, 0x61, 0x34,
|
||||
0x30, 0x64, 0x62, 0x65, 0x38, 0x35, 0x22, 0x3a,
|
||||
0x7b, 0x22, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63,
|
||||
0x65, 0x22, 0x3a, 0x22, 0x30, 0x78, 0x33, 0x33,
|
||||
0x62, 0x32, 0x65, 0x33, 0x63, 0x39, 0x66, 0x64,
|
||||
0x30, 0x38, 0x30, 0x34, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x22, 0x7d, 0x7d,
|
||||
0x2c, 0x22, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72,
|
||||
0x22, 0x3a, 0x22, 0x30, 0x78, 0x30, 0x22, 0x2c,
|
||||
0x22, 0x67, 0x61, 0x73, 0x55, 0x73, 0x65, 0x64,
|
||||
0x22, 0x3a, 0x22, 0x30, 0x78, 0x30, 0x22, 0x2c,
|
||||
0x22, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x48,
|
||||
0x61, 0x73, 0x68, 0x22, 0x3a, 0x22, 0x30, 0x78,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x22, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x39, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x13, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20,
|
||||
0x44, 0x41, 0x47, 0x20, 0x50, 0x61, 0x79, 0x6d,
|
||||
0x65, 0x6e, 0x74, 0x73, 0x73, 0x70, 0x64, 0x61,
|
||||
0x67, 0x76, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x02,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x30,
|
||||
0x9c, 0xe5, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x01, 0x3c, 0xb7, 0xd3, 0x84,
|
||||
0x2e, 0x8c, 0xee, 0x6a, 0x0e, 0xbd, 0x09, 0xf1,
|
||||
0xfe, 0x88, 0x4f, 0x68, 0x61, 0xe1, 0xb2, 0x9c,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
|
||||
0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x15, 0x53, 0x69, 0x6d, 0x70, 0x6c,
|
||||
0x65, 0x20, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x20,
|
||||
0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73,
|
||||
0x73, 0x70, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x76,
|
||||
0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
|
||||
0x00, 0x00, 0x00, 0x01, 0x3c, 0xb7, 0xd3, 0x84,
|
||||
0x2e, 0x8c, 0xee, 0x6a, 0x0e, 0xbd, 0x09, 0xf1,
|
||||
0xfe, 0x88, 0x4f, 0x68, 0x61, 0xe1, 0xb2, 0x9c,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x12, 0x30, 0x9c, 0xe5, 0x40, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x30, 0x39, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x53,
|
||||
0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x54, 0x69,
|
||||
0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x20,
|
||||
0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x74, 0x69,
|
||||
0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x5d, 0xbb, 0x75, 0x80,
|
||||
// Specify the genesis state of the AVM
|
||||
avmArgs := avm.BuildGenesisArgs{}
|
||||
{
|
||||
holders := []interface{}(nil)
|
||||
for _, addr := range Addresses {
|
||||
holders = append(holders, avm.Holder{
|
||||
Amount: json.Uint64(45 * units.MegaAva),
|
||||
Address: addr,
|
||||
})
|
||||
}
|
||||
avmArgs.GenesisData = map[string]avm.AssetDefinition{
|
||||
// The AVM starts out with one asset, $AVA
|
||||
"AVA": avm.AssetDefinition{
|
||||
Name: "AVA",
|
||||
Symbol: "AVA",
|
||||
Denomination: 9,
|
||||
InitialState: map[string][]interface{}{
|
||||
"fixedCap": holders,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
avmReply := avm.BuildGenesisReply{}
|
||||
|
||||
avmSS := avm.StaticService{}
|
||||
err := avmSS.BuildGenesis(nil, &avmArgs, &avmReply)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Specify the genesis state of Athereum (the built-in instance of the EVM)
|
||||
evmBalance, success := new(big.Int).SetString("33b2e3c9fd0804000000000", 16)
|
||||
if success != true {
|
||||
return nil
|
||||
}
|
||||
evmArgs := core.Genesis{
|
||||
Config: ¶ms.ChainConfig{
|
||||
ChainID: big.NewInt(43110),
|
||||
HomesteadBlock: big.NewInt(0),
|
||||
DAOForkBlock: big.NewInt(0),
|
||||
DAOForkSupport: true,
|
||||
EIP150Block: big.NewInt(0),
|
||||
EIP150Hash: common.HexToHash("0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0"),
|
||||
EIP155Block: big.NewInt(0),
|
||||
EIP158Block: big.NewInt(0),
|
||||
ByzantiumBlock: big.NewInt(0),
|
||||
ConstantinopleBlock: big.NewInt(0),
|
||||
PetersburgBlock: big.NewInt(0),
|
||||
},
|
||||
Nonce: 0,
|
||||
Timestamp: 0,
|
||||
ExtraData: []byte{0},
|
||||
GasLimit: 100000000,
|
||||
Difficulty: big.NewInt(0),
|
||||
Mixhash: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"),
|
||||
Coinbase: common.HexToAddress("0x0000000000000000000000000000000000000000"),
|
||||
Alloc: core.GenesisAlloc{
|
||||
common.HexToAddress(evm.GenesisTestAddr): core.GenesisAccount{
|
||||
Balance: evmBalance,
|
||||
},
|
||||
},
|
||||
Number: 0,
|
||||
GasUsed: 0,
|
||||
ParentHash: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"),
|
||||
}
|
||||
evmSS := evm.StaticService{}
|
||||
evmReply, err := evmSS.BuildGenesis(nil, &evmArgs)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Specify the genesis state of the simple payments DAG
|
||||
spdagvmArgs := spdagvm.BuildGenesisArgs{}
|
||||
for _, addr := range ParsedAddresses {
|
||||
spdagvmArgs.Outputs = append(spdagvmArgs.Outputs,
|
||||
spdagvm.APIOutput{
|
||||
Amount: json.Uint64(20 * units.KiloAva),
|
||||
Threshold: 1,
|
||||
Addresses: []ids.ShortID{addr},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
spdagvmReply := spdagvm.BuildGenesisReply{}
|
||||
spdagvmSS := spdagvm.StaticService{}
|
||||
if err := spdagvmSS.BuildGenesis(nil, &spdagvmArgs, &spdagvmReply); err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Specify the genesis state of the simple payments chain
|
||||
spchainvmArgs := spchainvm.BuildGenesisArgs{}
|
||||
for _, addr := range ParsedAddresses {
|
||||
spchainvmArgs.Accounts = append(spchainvmArgs.Accounts,
|
||||
spchainvm.APIAccount{
|
||||
Address: addr,
|
||||
Balance: json.Uint64(20 * units.KiloAva),
|
||||
},
|
||||
)
|
||||
}
|
||||
spchainvmReply := spchainvm.BuildGenesisReply{}
|
||||
|
||||
spchainvmSS := spchainvm.StaticService{}
|
||||
if err := spchainvmSS.BuildGenesis(nil, &spchainvmArgs, &spchainvmReply); err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Specify the initial state of the Platform Chain
|
||||
platformvmArgs := platformvm.BuildGenesisArgs{
|
||||
NetworkID: json.Uint32(networkID),
|
||||
}
|
||||
for _, addr := range ParsedAddresses {
|
||||
platformvmArgs.Accounts = append(platformvmArgs.Accounts,
|
||||
platformvm.APIAccount{
|
||||
Address: addr,
|
||||
Balance: json.Uint64(20 * units.KiloAva),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
genesisTime := time.Date(
|
||||
/*year=*/ 2019,
|
||||
/*month=*/ time.November,
|
||||
/*day=*/ 1,
|
||||
/*hour=*/ 0,
|
||||
/*minute=*/ 0,
|
||||
/*second=*/ 0,
|
||||
/*nano-second=*/ 0,
|
||||
/*location=*/ time.UTC,
|
||||
)
|
||||
stakingDuration := 365 * 24 * time.Hour // ~ 1 year
|
||||
endStakingTime := genesisTime.Add(stakingDuration)
|
||||
|
||||
for i, validatorID := range ParsedStakerIDs {
|
||||
weight := json.Uint64(20 * units.KiloAva)
|
||||
platformvmArgs.Validators = append(platformvmArgs.Validators,
|
||||
platformvm.APIDefaultSubnetValidator{
|
||||
APIValidator: platformvm.APIValidator{
|
||||
StartTime: json.Uint64(genesisTime.Unix()),
|
||||
EndTime: json.Uint64(endStakingTime.Unix()),
|
||||
Weight: &weight,
|
||||
ID: validatorID,
|
||||
},
|
||||
Destination: ParsedAddresses[i%len(ParsedAddresses)],
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// Specify the chains that exist upon this network's creation
|
||||
platformvmArgs.Chains = []platformvm.APIChain{
|
||||
platformvm.APIChain{
|
||||
GenesisData: avmReply.Bytes,
|
||||
VMID: avm.ID,
|
||||
FxIDs: []ids.ID{
|
||||
secp256k1fx.ID,
|
||||
nftfx.ID,
|
||||
},
|
||||
Name: "X-Chain",
|
||||
},
|
||||
platformvm.APIChain{
|
||||
GenesisData: evmReply,
|
||||
VMID: evm.ID,
|
||||
Name: "C-Chain",
|
||||
},
|
||||
platformvm.APIChain{
|
||||
GenesisData: spdagvmReply.Bytes,
|
||||
VMID: spdagvm.ID,
|
||||
Name: "Simple DAG Payments",
|
||||
},
|
||||
platformvm.APIChain{
|
||||
GenesisData: spchainvmReply.Bytes,
|
||||
VMID: spchainvm.ID,
|
||||
Name: "Simple Chain Payments",
|
||||
},
|
||||
platformvm.APIChain{
|
||||
GenesisData: formatting.CB58{Bytes: []byte{}}, // There is no genesis data
|
||||
VMID: timestampvm.ID,
|
||||
Name: "Simple Timestamp Server",
|
||||
},
|
||||
}
|
||||
|
||||
platformvmArgs.Time = json.Uint64(genesisTime.Unix())
|
||||
platformvmReply := platformvm.BuildGenesisReply{}
|
||||
|
||||
platformvmSS := platformvm.StaticService{}
|
||||
if err := platformvmSS.BuildGenesis(nil, &platformvmArgs, &platformvmReply); err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return platformvmReply.Bytes.Bytes
|
||||
}
|
||||
|
||||
// VMGenesis ...
|
||||
|
|
|
@ -39,6 +39,7 @@ import (
|
|||
"github.com/ava-labs/gecko/vms"
|
||||
"github.com/ava-labs/gecko/vms/avm"
|
||||
"github.com/ava-labs/gecko/vms/evm"
|
||||
"github.com/ava-labs/gecko/vms/nftfx"
|
||||
"github.com/ava-labs/gecko/vms/platformvm"
|
||||
"github.com/ava-labs/gecko/vms/secp256k1fx"
|
||||
"github.com/ava-labs/gecko/vms/spchainvm"
|
||||
|
@ -333,8 +334,9 @@ func (n *Node) initVMManager() {
|
|||
n.vmManager.RegisterVMFactory(evm.ID, &evm.Factory{})
|
||||
n.vmManager.RegisterVMFactory(spdagvm.ID, &spdagvm.Factory{TxFee: n.Config.AvaTxFee})
|
||||
n.vmManager.RegisterVMFactory(spchainvm.ID, &spchainvm.Factory{})
|
||||
n.vmManager.RegisterVMFactory(secp256k1fx.ID, &secp256k1fx.Factory{})
|
||||
n.vmManager.RegisterVMFactory(timestampvm.ID, ×tampvm.Factory{})
|
||||
n.vmManager.RegisterVMFactory(secp256k1fx.ID, &secp256k1fx.Factory{})
|
||||
n.vmManager.RegisterVMFactory(nftfx.ID, &nftfx.Factory{})
|
||||
}
|
||||
|
||||
// Create the EventDispatcher used for hooking events
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
|
||||
"github.com/ava-labs/gecko/ids"
|
||||
"github.com/ava-labs/gecko/utils/formatting"
|
||||
"github.com/ava-labs/gecko/utils/wrappers"
|
||||
"github.com/ava-labs/gecko/vms/components/codec"
|
||||
"github.com/ava-labs/gecko/vms/secp256k1fx"
|
||||
|
||||
|
@ -44,17 +45,24 @@ type BuildGenesisReply struct {
|
|||
// BuildGenesis returns the UTXOs such that at least one address in [args.Addresses] is
|
||||
// referenced in the UTXO.
|
||||
func (*StaticService) BuildGenesis(_ *http.Request, args *BuildGenesisArgs, reply *BuildGenesisReply) error {
|
||||
errs := wrappers.Errs{}
|
||||
|
||||
c := codec.NewDefault()
|
||||
c.RegisterType(&BaseTx{})
|
||||
c.RegisterType(&CreateAssetTx{})
|
||||
c.RegisterType(&OperationTx{})
|
||||
c.RegisterType(&ImportTx{})
|
||||
c.RegisterType(&ExportTx{})
|
||||
c.RegisterType(&secp256k1fx.TransferInput{})
|
||||
c.RegisterType(&secp256k1fx.MintOutput{})
|
||||
c.RegisterType(&secp256k1fx.TransferOutput{})
|
||||
c.RegisterType(&secp256k1fx.MintOperation{})
|
||||
c.RegisterType(&secp256k1fx.Credential{})
|
||||
errs.Add(
|
||||
c.RegisterType(&BaseTx{}),
|
||||
c.RegisterType(&CreateAssetTx{}),
|
||||
c.RegisterType(&OperationTx{}),
|
||||
c.RegisterType(&ImportTx{}),
|
||||
c.RegisterType(&ExportTx{}),
|
||||
c.RegisterType(&secp256k1fx.TransferInput{}),
|
||||
c.RegisterType(&secp256k1fx.MintOutput{}),
|
||||
c.RegisterType(&secp256k1fx.TransferOutput{}),
|
||||
c.RegisterType(&secp256k1fx.MintOperation{}),
|
||||
c.RegisterType(&secp256k1fx.Credential{}),
|
||||
)
|
||||
if errs.Errored() {
|
||||
return errs.Err
|
||||
}
|
||||
|
||||
g := Genesis{}
|
||||
for assetAlias, assetDefinition := range args.GenesisData {
|
||||
|
|
|
@ -116,24 +116,24 @@ func (vm *VM) Initialize(
|
|||
vm.Aliaser.Initialize()
|
||||
|
||||
vm.pubsub = cjson.NewPubSubServer(ctx)
|
||||
c := codec.NewDefault()
|
||||
|
||||
errs := wrappers.Errs{}
|
||||
errs.Add(
|
||||
vm.pubsub.Register("accepted"),
|
||||
vm.pubsub.Register("rejected"),
|
||||
vm.pubsub.Register("verified"),
|
||||
|
||||
c.RegisterType(&BaseTx{}),
|
||||
c.RegisterType(&CreateAssetTx{}),
|
||||
c.RegisterType(&OperationTx{}),
|
||||
c.RegisterType(&ImportTx{}),
|
||||
c.RegisterType(&ExportTx{}),
|
||||
)
|
||||
if errs.Errored() {
|
||||
return errs.Err
|
||||
}
|
||||
|
||||
c := codec.NewDefault()
|
||||
c.RegisterType(&BaseTx{})
|
||||
c.RegisterType(&CreateAssetTx{})
|
||||
c.RegisterType(&OperationTx{})
|
||||
c.RegisterType(&ImportTx{})
|
||||
c.RegisterType(&ExportTx{})
|
||||
|
||||
vm.fxs = make([]*parsedFx, len(fxs))
|
||||
for i, fxContainer := range fxs {
|
||||
if fxContainer == nil {
|
||||
|
|
|
@ -18,6 +18,7 @@ import (
|
|||
"github.com/ava-labs/gecko/vms/components/ava"
|
||||
"github.com/ava-labs/gecko/vms/components/codec"
|
||||
"github.com/ava-labs/gecko/vms/components/verify"
|
||||
"github.com/ava-labs/gecko/vms/nftfx"
|
||||
"github.com/ava-labs/gecko/vms/secp256k1fx"
|
||||
)
|
||||
|
||||
|
@ -696,3 +697,159 @@ func TestIssueDependentTx(t *testing.T) {
|
|||
t.Fatalf("Should have returned %d tx(s)", 2)
|
||||
}
|
||||
}
|
||||
|
||||
// Test issuing a transaction that creates an NFT family
|
||||
func TestIssueNFT(t *testing.T) {
|
||||
genesisBytes := BuildGenesisTest(t)
|
||||
|
||||
issuer := make(chan common.Message, 1)
|
||||
|
||||
ctx.Lock.Lock()
|
||||
vm := &VM{}
|
||||
err := vm.Initialize(
|
||||
ctx,
|
||||
memdb.New(),
|
||||
genesisBytes,
|
||||
issuer,
|
||||
[]*common.Fx{
|
||||
&common.Fx{
|
||||
ID: ids.Empty.Prefix(0),
|
||||
Fx: &secp256k1fx.Fx{},
|
||||
},
|
||||
&common.Fx{
|
||||
ID: ids.Empty.Prefix(1),
|
||||
Fx: &nftfx.Fx{},
|
||||
},
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
vm.batchTimeout = 0
|
||||
|
||||
createAssetTx := &Tx{UnsignedTx: &CreateAssetTx{
|
||||
BaseTx: BaseTx{
|
||||
NetID: networkID,
|
||||
BCID: chainID,
|
||||
},
|
||||
Name: "Team Rocket",
|
||||
Symbol: "TR",
|
||||
Denomination: 0,
|
||||
States: []*InitialState{&InitialState{
|
||||
FxID: 1,
|
||||
Outs: []verify.Verifiable{
|
||||
&nftfx.MintOutput{
|
||||
GroupID: 1,
|
||||
OutputOwners: secp256k1fx.OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{keys[0].PublicKey().Address()},
|
||||
},
|
||||
},
|
||||
&nftfx.MintOutput{
|
||||
GroupID: 2,
|
||||
OutputOwners: secp256k1fx.OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{keys[0].PublicKey().Address()},
|
||||
},
|
||||
},
|
||||
},
|
||||
}},
|
||||
}}
|
||||
|
||||
b, err := vm.codec.Marshal(createAssetTx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
createAssetTx.Initialize(b)
|
||||
|
||||
if _, err = vm.IssueTx(createAssetTx.Bytes(), nil); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
mintNFTTx := &Tx{UnsignedTx: &OperationTx{
|
||||
BaseTx: BaseTx{
|
||||
NetID: networkID,
|
||||
BCID: chainID,
|
||||
},
|
||||
Ops: []*Operation{&Operation{
|
||||
Asset: ava.Asset{ID: createAssetTx.ID()},
|
||||
UTXOIDs: []*ava.UTXOID{&ava.UTXOID{
|
||||
TxID: createAssetTx.ID(),
|
||||
OutputIndex: 0,
|
||||
}},
|
||||
Op: &nftfx.MintOperation{
|
||||
MintInput: secp256k1fx.Input{
|
||||
SigIndices: []uint32{0},
|
||||
},
|
||||
GroupID: 1,
|
||||
Payload: []byte{'h', 'e', 'l', 'l', 'o'},
|
||||
Outputs: []*secp256k1fx.OutputOwners{
|
||||
&secp256k1fx.OutputOwners{},
|
||||
},
|
||||
},
|
||||
}},
|
||||
}}
|
||||
|
||||
unsignedBytes, err := vm.codec.Marshal(&mintNFTTx.UnsignedTx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
key := keys[0]
|
||||
sig, err := key.Sign(unsignedBytes)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
fixedSig := [crypto.SECP256K1RSigLen]byte{}
|
||||
copy(fixedSig[:], sig)
|
||||
|
||||
mintNFTTx.Creds = append(mintNFTTx.Creds, &nftfx.Credential{Credential: secp256k1fx.Credential{
|
||||
Sigs: [][crypto.SECP256K1RSigLen]byte{
|
||||
fixedSig,
|
||||
}},
|
||||
})
|
||||
|
||||
b, err = vm.codec.Marshal(mintNFTTx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
mintNFTTx.Initialize(b)
|
||||
|
||||
if _, err = vm.IssueTx(mintNFTTx.Bytes(), nil); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
transferNFTTx := &Tx{UnsignedTx: &OperationTx{
|
||||
BaseTx: BaseTx{
|
||||
NetID: networkID,
|
||||
BCID: chainID,
|
||||
},
|
||||
Ops: []*Operation{&Operation{
|
||||
Asset: ava.Asset{ID: createAssetTx.ID()},
|
||||
UTXOIDs: []*ava.UTXOID{&ava.UTXOID{
|
||||
TxID: mintNFTTx.ID(),
|
||||
OutputIndex: 0,
|
||||
}},
|
||||
Op: &nftfx.TransferOperation{
|
||||
Input: secp256k1fx.Input{},
|
||||
Output: nftfx.TransferOutput{
|
||||
GroupID: 1,
|
||||
Payload: []byte{'h', 'e', 'l', 'l', 'o'},
|
||||
OutputOwners: secp256k1fx.OutputOwners{},
|
||||
},
|
||||
},
|
||||
}},
|
||||
}}
|
||||
|
||||
transferNFTTx.Creds = append(transferNFTTx.Creds, &nftfx.Credential{})
|
||||
|
||||
b, err = vm.codec.Marshal(transferNFTTx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
transferNFTTx.Initialize(b)
|
||||
|
||||
if _, err = vm.IssueTx(transferNFTTx.Bytes(), nil); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
package nftfx
|
||||
|
||||
import (
|
||||
"github.com/ava-labs/gecko/vms/secp256k1fx"
|
||||
)
|
||||
|
||||
// Credential ...
|
||||
type Credential struct {
|
||||
secp256k1fx.Credential `serialize:"true"`
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package nftfx
|
||||
|
||||
import (
|
||||
"github.com/ava-labs/gecko/ids"
|
||||
)
|
||||
|
||||
// ID that this Fx uses when labeled
|
||||
var (
|
||||
ID = ids.NewID([32]byte{'n', 'f', 't', 'f', 'x'})
|
||||
)
|
||||
|
||||
// Factory ...
|
||||
type Factory struct{}
|
||||
|
||||
// New ...
|
||||
func (f *Factory) New() interface{} { return &Fx{} }
|
|
@ -0,0 +1,12 @@
|
|||
package nftfx
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestFactory(t *testing.T) {
|
||||
factory := Factory{}
|
||||
if fx := factory.New(); fx == nil {
|
||||
t.Fatalf("Factory.New returned nil")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,118 @@
|
|||
package nftfx
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
|
||||
"github.com/ava-labs/gecko/utils/wrappers"
|
||||
"github.com/ava-labs/gecko/vms/components/verify"
|
||||
"github.com/ava-labs/gecko/vms/secp256k1fx"
|
||||
)
|
||||
|
||||
var (
|
||||
errWrongTxType = errors.New("wrong tx type")
|
||||
errWrongUTXOType = errors.New("wrong utxo type")
|
||||
errWrongOperationType = errors.New("wrong operation type")
|
||||
errWrongCredentialType = errors.New("wrong credential type")
|
||||
|
||||
errNoUTXOs = errors.New("an operation must consume at least one UTXO")
|
||||
errWrongNumberOfUTXOs = errors.New("wrong number of UTXOs for the operation")
|
||||
errWrongNumberOfCreds = errors.New("wrong number of credentials for the operation")
|
||||
|
||||
errWrongUniqueID = errors.New("wrong unique ID provided")
|
||||
errWrongBytes = errors.New("wrong bytes provided")
|
||||
|
||||
errCantTransfer = errors.New("cant transfer with this fx")
|
||||
)
|
||||
|
||||
// Fx ...
|
||||
type Fx struct{ secp256k1fx.Fx }
|
||||
|
||||
// Initialize ...
|
||||
func (fx *Fx) Initialize(vmIntf interface{}) error {
|
||||
if err := fx.InitializeVM(vmIntf); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log := fx.VM.Logger()
|
||||
log.Debug("Initializing nft fx")
|
||||
|
||||
c := fx.VM.Codec()
|
||||
errs := wrappers.Errs{}
|
||||
errs.Add(
|
||||
c.RegisterType(&MintOutput{}),
|
||||
c.RegisterType(&TransferOutput{}),
|
||||
c.RegisterType(&MintOperation{}),
|
||||
c.RegisterType(&TransferOperation{}),
|
||||
c.RegisterType(&Credential{}),
|
||||
)
|
||||
return errs.Err
|
||||
}
|
||||
|
||||
// VerifyOperation ...
|
||||
func (fx *Fx) VerifyOperation(txIntf, opIntf, credIntf interface{}, utxosIntf []interface{}) error {
|
||||
tx, ok := txIntf.(secp256k1fx.Tx)
|
||||
switch {
|
||||
case !ok:
|
||||
return errWrongTxType
|
||||
case len(utxosIntf) != 1:
|
||||
return errWrongNumberOfUTXOs
|
||||
}
|
||||
|
||||
cred, ok := credIntf.(*Credential)
|
||||
if !ok {
|
||||
return errWrongCredentialType
|
||||
}
|
||||
|
||||
switch op := opIntf.(type) {
|
||||
case *MintOperation:
|
||||
return fx.VerifyMintOperation(tx, op, cred, utxosIntf[0])
|
||||
case *TransferOperation:
|
||||
return fx.VerifyTransferOperation(tx, op, cred, utxosIntf[0])
|
||||
default:
|
||||
return errWrongOperationType
|
||||
}
|
||||
}
|
||||
|
||||
// VerifyMintOperation ...
|
||||
func (fx *Fx) VerifyMintOperation(tx secp256k1fx.Tx, op *MintOperation, cred *Credential, utxoIntf interface{}) error {
|
||||
out, ok := utxoIntf.(*MintOutput)
|
||||
if !ok {
|
||||
return errWrongUTXOType
|
||||
}
|
||||
|
||||
if err := verify.All(op, cred, out); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch {
|
||||
case out.GroupID != op.GroupID:
|
||||
return errWrongUniqueID
|
||||
default:
|
||||
return fx.Fx.VerifyCredentials(tx, &op.MintInput, &cred.Credential, &out.OutputOwners)
|
||||
}
|
||||
}
|
||||
|
||||
// VerifyTransferOperation ...
|
||||
func (fx *Fx) VerifyTransferOperation(tx secp256k1fx.Tx, op *TransferOperation, cred *Credential, utxoIntf interface{}) error {
|
||||
out, ok := utxoIntf.(*TransferOutput)
|
||||
if !ok {
|
||||
return errWrongUTXOType
|
||||
}
|
||||
|
||||
if err := verify.All(op, cred, out); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch {
|
||||
case out.GroupID != op.Output.GroupID:
|
||||
return errWrongUniqueID
|
||||
case !bytes.Equal(out.Payload, op.Output.Payload):
|
||||
return errWrongBytes
|
||||
default:
|
||||
return fx.VerifyCredentials(tx, &op.Input, &cred.Credential, &out.OutputOwners)
|
||||
}
|
||||
}
|
||||
|
||||
// VerifyTransfer ...
|
||||
func (fx *Fx) VerifyTransfer(_, _, _, _ interface{}) error { return errCantTransfer }
|
|
@ -0,0 +1,618 @@
|
|||
package nftfx
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ava-labs/gecko/ids"
|
||||
"github.com/ava-labs/gecko/utils/crypto"
|
||||
"github.com/ava-labs/gecko/utils/hashing"
|
||||
"github.com/ava-labs/gecko/utils/logging"
|
||||
"github.com/ava-labs/gecko/utils/timer"
|
||||
"github.com/ava-labs/gecko/vms/components/codec"
|
||||
"github.com/ava-labs/gecko/vms/secp256k1fx"
|
||||
)
|
||||
|
||||
var (
|
||||
txBytes = []byte{0, 1, 2, 3, 4, 5}
|
||||
sigBytes = [crypto.SECP256K1RSigLen]byte{
|
||||
0x0e, 0x33, 0x4e, 0xbc, 0x67, 0xa7, 0x3f, 0xe8,
|
||||
0x24, 0x33, 0xac, 0xa3, 0x47, 0x88, 0xa6, 0x3d,
|
||||
0x58, 0xe5, 0x8e, 0xf0, 0x3a, 0xd5, 0x84, 0xf1,
|
||||
0xbc, 0xa3, 0xb2, 0xd2, 0x5d, 0x51, 0xd6, 0x9b,
|
||||
0x0f, 0x28, 0x5d, 0xcd, 0x3f, 0x71, 0x17, 0x0a,
|
||||
0xf9, 0xbf, 0x2d, 0xb1, 0x10, 0x26, 0x5c, 0xe9,
|
||||
0xdc, 0xc3, 0x9d, 0x7a, 0x01, 0x50, 0x9d, 0xe8,
|
||||
0x35, 0xbd, 0xcb, 0x29, 0x3a, 0xd1, 0x49, 0x32,
|
||||
0x00,
|
||||
}
|
||||
addrBytes = [hashing.AddrLen]byte{
|
||||
0x01, 0x5c, 0xce, 0x6c, 0x55, 0xd6, 0xb5, 0x09,
|
||||
0x84, 0x5c, 0x8c, 0x4e, 0x30, 0xbe, 0xd9, 0x8d,
|
||||
0x39, 0x1a, 0xe7, 0xf0,
|
||||
}
|
||||
)
|
||||
|
||||
func TestFxInitialize(t *testing.T) {
|
||||
vm := secp256k1fx.TestVM{
|
||||
CLK: new(timer.Clock),
|
||||
Code: codec.NewDefault(),
|
||||
Log: logging.NoLog{},
|
||||
}
|
||||
fx := Fx{}
|
||||
err := fx.Initialize(&vm)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFxInitializeInvalid(t *testing.T) {
|
||||
fx := Fx{}
|
||||
err := fx.Initialize(nil)
|
||||
if err == nil {
|
||||
t.Fatalf("Should have returned an error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFxVerifyMintOperation(t *testing.T) {
|
||||
vm := secp256k1fx.TestVM{
|
||||
CLK: new(timer.Clock),
|
||||
Code: codec.NewDefault(),
|
||||
Log: logging.NoLog{},
|
||||
}
|
||||
date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC)
|
||||
vm.CLK.Set(date)
|
||||
|
||||
fx := Fx{}
|
||||
if err := fx.Initialize(&vm); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tx := &secp256k1fx.TestTx{
|
||||
Bytes: txBytes,
|
||||
}
|
||||
cred := &Credential{Credential: secp256k1fx.Credential{
|
||||
Sigs: [][crypto.SECP256K1RSigLen]byte{
|
||||
sigBytes,
|
||||
},
|
||||
}}
|
||||
utxo := &MintOutput{OutputOwners: secp256k1fx.OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
},
|
||||
}}
|
||||
op := &MintOperation{
|
||||
MintInput: secp256k1fx.Input{
|
||||
SigIndices: []uint32{0},
|
||||
},
|
||||
}
|
||||
|
||||
utxos := []interface{}{utxo}
|
||||
if err := fx.VerifyOperation(tx, op, cred, utxos); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFxVerifyMintOperationWrongTx(t *testing.T) {
|
||||
vm := secp256k1fx.TestVM{
|
||||
CLK: new(timer.Clock),
|
||||
Code: codec.NewDefault(),
|
||||
Log: logging.NoLog{},
|
||||
}
|
||||
date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC)
|
||||
vm.CLK.Set(date)
|
||||
|
||||
fx := Fx{}
|
||||
if err := fx.Initialize(&vm); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cred := &Credential{Credential: secp256k1fx.Credential{
|
||||
Sigs: [][crypto.SECP256K1RSigLen]byte{
|
||||
sigBytes,
|
||||
},
|
||||
}}
|
||||
utxo := &MintOutput{OutputOwners: secp256k1fx.OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
},
|
||||
}}
|
||||
op := &MintOperation{
|
||||
MintInput: secp256k1fx.Input{
|
||||
SigIndices: []uint32{0},
|
||||
},
|
||||
}
|
||||
|
||||
utxos := []interface{}{utxo}
|
||||
if err := fx.VerifyOperation(nil, op, cred, utxos); err == nil {
|
||||
t.Fatalf("VerifyOperation should have errored due to an invalid tx")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFxVerifyMintOperationWrongNumberUTXOs(t *testing.T) {
|
||||
vm := secp256k1fx.TestVM{
|
||||
CLK: new(timer.Clock),
|
||||
Code: codec.NewDefault(),
|
||||
Log: logging.NoLog{},
|
||||
}
|
||||
date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC)
|
||||
vm.CLK.Set(date)
|
||||
|
||||
fx := Fx{}
|
||||
if err := fx.Initialize(&vm); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tx := &secp256k1fx.TestTx{
|
||||
Bytes: txBytes,
|
||||
}
|
||||
cred := &Credential{Credential: secp256k1fx.Credential{
|
||||
Sigs: [][crypto.SECP256K1RSigLen]byte{
|
||||
sigBytes,
|
||||
},
|
||||
}}
|
||||
op := &MintOperation{
|
||||
MintInput: secp256k1fx.Input{
|
||||
SigIndices: []uint32{0},
|
||||
},
|
||||
}
|
||||
|
||||
utxos := []interface{}{}
|
||||
if err := fx.VerifyOperation(tx, op, cred, utxos); err == nil {
|
||||
t.Fatalf("VerifyOperation should have errored due to not enough utxos")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFxVerifyMintOperationWrongCredential(t *testing.T) {
|
||||
vm := secp256k1fx.TestVM{
|
||||
CLK: new(timer.Clock),
|
||||
Code: codec.NewDefault(),
|
||||
Log: logging.NoLog{},
|
||||
}
|
||||
date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC)
|
||||
vm.CLK.Set(date)
|
||||
|
||||
fx := Fx{}
|
||||
if err := fx.Initialize(&vm); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tx := &secp256k1fx.TestTx{
|
||||
Bytes: txBytes,
|
||||
}
|
||||
utxo := &MintOutput{OutputOwners: secp256k1fx.OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
},
|
||||
}}
|
||||
op := &MintOperation{
|
||||
MintInput: secp256k1fx.Input{
|
||||
SigIndices: []uint32{0},
|
||||
},
|
||||
}
|
||||
|
||||
utxos := []interface{}{utxo}
|
||||
if err := fx.VerifyOperation(tx, op, nil, utxos); err == nil {
|
||||
t.Fatalf("VerifyOperation should have errored due to a bad credential")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFxVerifyMintOperationInvalidUTXO(t *testing.T) {
|
||||
vm := secp256k1fx.TestVM{
|
||||
CLK: new(timer.Clock),
|
||||
Code: codec.NewDefault(),
|
||||
Log: logging.NoLog{},
|
||||
}
|
||||
date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC)
|
||||
vm.CLK.Set(date)
|
||||
|
||||
fx := Fx{}
|
||||
if err := fx.Initialize(&vm); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tx := &secp256k1fx.TestTx{
|
||||
Bytes: txBytes,
|
||||
}
|
||||
cred := &Credential{Credential: secp256k1fx.Credential{
|
||||
Sigs: [][crypto.SECP256K1RSigLen]byte{
|
||||
sigBytes,
|
||||
},
|
||||
}}
|
||||
op := &MintOperation{
|
||||
MintInput: secp256k1fx.Input{
|
||||
SigIndices: []uint32{0},
|
||||
},
|
||||
}
|
||||
|
||||
utxos := []interface{}{nil}
|
||||
if err := fx.VerifyOperation(tx, op, cred, utxos); err == nil {
|
||||
t.Fatalf("VerifyOperation should have errored due to an invalid utxo")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFxVerifyMintOperationFailingVerification(t *testing.T) {
|
||||
vm := secp256k1fx.TestVM{
|
||||
CLK: new(timer.Clock),
|
||||
Code: codec.NewDefault(),
|
||||
Log: logging.NoLog{},
|
||||
}
|
||||
date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC)
|
||||
vm.CLK.Set(date)
|
||||
|
||||
fx := Fx{}
|
||||
if err := fx.Initialize(&vm); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tx := &secp256k1fx.TestTx{
|
||||
Bytes: txBytes,
|
||||
}
|
||||
cred := &Credential{Credential: secp256k1fx.Credential{
|
||||
Sigs: [][crypto.SECP256K1RSigLen]byte{
|
||||
sigBytes,
|
||||
},
|
||||
}}
|
||||
utxo := &MintOutput{OutputOwners: secp256k1fx.OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
ids.ShortEmpty,
|
||||
},
|
||||
}}
|
||||
op := &MintOperation{
|
||||
MintInput: secp256k1fx.Input{
|
||||
SigIndices: []uint32{0},
|
||||
},
|
||||
}
|
||||
|
||||
utxos := []interface{}{utxo}
|
||||
if err := fx.VerifyOperation(tx, op, cred, utxos); err == nil {
|
||||
t.Fatalf("VerifyOperation should have errored due to an invalid utxo output")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFxVerifyMintOperationInvalidGroupID(t *testing.T) {
|
||||
vm := secp256k1fx.TestVM{
|
||||
CLK: new(timer.Clock),
|
||||
Code: codec.NewDefault(),
|
||||
Log: logging.NoLog{},
|
||||
}
|
||||
date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC)
|
||||
vm.CLK.Set(date)
|
||||
|
||||
fx := Fx{}
|
||||
if err := fx.Initialize(&vm); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tx := &secp256k1fx.TestTx{
|
||||
Bytes: txBytes,
|
||||
}
|
||||
cred := &Credential{Credential: secp256k1fx.Credential{
|
||||
Sigs: [][crypto.SECP256K1RSigLen]byte{
|
||||
sigBytes,
|
||||
},
|
||||
}}
|
||||
utxo := &MintOutput{OutputOwners: secp256k1fx.OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
},
|
||||
}}
|
||||
op := &MintOperation{
|
||||
MintInput: secp256k1fx.Input{
|
||||
SigIndices: []uint32{0},
|
||||
},
|
||||
GroupID: 1,
|
||||
}
|
||||
|
||||
utxos := []interface{}{utxo}
|
||||
if err := fx.VerifyOperation(tx, op, cred, utxos); err == nil {
|
||||
t.Fatalf("VerifyOperation should have errored due to an invalid Group ID")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFxVerifyTransferOperation(t *testing.T) {
|
||||
vm := secp256k1fx.TestVM{
|
||||
CLK: new(timer.Clock),
|
||||
Code: codec.NewDefault(),
|
||||
Log: logging.NoLog{},
|
||||
}
|
||||
date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC)
|
||||
vm.CLK.Set(date)
|
||||
|
||||
fx := Fx{}
|
||||
if err := fx.Initialize(&vm); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tx := &secp256k1fx.TestTx{
|
||||
Bytes: txBytes,
|
||||
}
|
||||
cred := &Credential{Credential: secp256k1fx.Credential{
|
||||
Sigs: [][crypto.SECP256K1RSigLen]byte{
|
||||
sigBytes,
|
||||
},
|
||||
}}
|
||||
utxo := &TransferOutput{
|
||||
GroupID: 1,
|
||||
Payload: []byte{2},
|
||||
OutputOwners: secp256k1fx.OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
},
|
||||
},
|
||||
}
|
||||
op := &TransferOperation{
|
||||
Input: secp256k1fx.Input{
|
||||
SigIndices: []uint32{0},
|
||||
},
|
||||
Output: TransferOutput{
|
||||
GroupID: 1,
|
||||
Payload: []byte{2},
|
||||
OutputOwners: secp256k1fx.OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.ShortEmpty,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
utxos := []interface{}{utxo}
|
||||
if err := fx.VerifyOperation(tx, op, cred, utxos); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFxVerifyTransferOperationWrongUTXO(t *testing.T) {
|
||||
vm := secp256k1fx.TestVM{
|
||||
CLK: new(timer.Clock),
|
||||
Code: codec.NewDefault(),
|
||||
Log: logging.NoLog{},
|
||||
}
|
||||
date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC)
|
||||
vm.CLK.Set(date)
|
||||
|
||||
fx := Fx{}
|
||||
if err := fx.Initialize(&vm); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tx := &secp256k1fx.TestTx{
|
||||
Bytes: txBytes,
|
||||
}
|
||||
cred := &Credential{Credential: secp256k1fx.Credential{
|
||||
Sigs: [][crypto.SECP256K1RSigLen]byte{
|
||||
sigBytes,
|
||||
},
|
||||
}}
|
||||
op := &TransferOperation{
|
||||
Input: secp256k1fx.Input{
|
||||
SigIndices: []uint32{0},
|
||||
},
|
||||
Output: TransferOutput{
|
||||
GroupID: 1,
|
||||
Payload: []byte{2},
|
||||
OutputOwners: secp256k1fx.OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.ShortEmpty,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
utxos := []interface{}{nil}
|
||||
if err := fx.VerifyOperation(tx, op, cred, utxos); err == nil {
|
||||
t.Fatalf("VerifyOperation should have errored due to an invalid utxo")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFxVerifyTransferOperationFailedVerify(t *testing.T) {
|
||||
vm := secp256k1fx.TestVM{
|
||||
CLK: new(timer.Clock),
|
||||
Code: codec.NewDefault(),
|
||||
Log: logging.NoLog{},
|
||||
}
|
||||
date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC)
|
||||
vm.CLK.Set(date)
|
||||
|
||||
fx := Fx{}
|
||||
if err := fx.Initialize(&vm); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tx := &secp256k1fx.TestTx{
|
||||
Bytes: txBytes,
|
||||
}
|
||||
cred := &Credential{Credential: secp256k1fx.Credential{
|
||||
Sigs: [][crypto.SECP256K1RSigLen]byte{
|
||||
sigBytes,
|
||||
},
|
||||
}}
|
||||
utxo := &TransferOutput{
|
||||
GroupID: 1,
|
||||
Payload: []byte{2},
|
||||
OutputOwners: secp256k1fx.OutputOwners{
|
||||
Threshold: 1,
|
||||
},
|
||||
}
|
||||
op := &TransferOperation{
|
||||
Input: secp256k1fx.Input{
|
||||
SigIndices: []uint32{0},
|
||||
},
|
||||
Output: TransferOutput{
|
||||
GroupID: 1,
|
||||
Payload: []byte{2},
|
||||
OutputOwners: secp256k1fx.OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.ShortEmpty,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
utxos := []interface{}{utxo}
|
||||
if err := fx.VerifyOperation(tx, op, cred, utxos); err == nil {
|
||||
t.Fatalf("VerifyOperation should have errored due to an invalid utxo output")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFxVerifyTransferOperationWrongGroupID(t *testing.T) {
|
||||
vm := secp256k1fx.TestVM{
|
||||
CLK: new(timer.Clock),
|
||||
Code: codec.NewDefault(),
|
||||
Log: logging.NoLog{},
|
||||
}
|
||||
date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC)
|
||||
vm.CLK.Set(date)
|
||||
|
||||
fx := Fx{}
|
||||
if err := fx.Initialize(&vm); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tx := &secp256k1fx.TestTx{
|
||||
Bytes: txBytes,
|
||||
}
|
||||
cred := &Credential{Credential: secp256k1fx.Credential{
|
||||
Sigs: [][crypto.SECP256K1RSigLen]byte{
|
||||
sigBytes,
|
||||
},
|
||||
}}
|
||||
utxo := &TransferOutput{
|
||||
GroupID: 1,
|
||||
Payload: []byte{2},
|
||||
OutputOwners: secp256k1fx.OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
},
|
||||
},
|
||||
}
|
||||
op := &TransferOperation{
|
||||
Input: secp256k1fx.Input{
|
||||
SigIndices: []uint32{0},
|
||||
},
|
||||
Output: TransferOutput{
|
||||
GroupID: 2,
|
||||
Payload: []byte{2},
|
||||
OutputOwners: secp256k1fx.OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.ShortEmpty,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
utxos := []interface{}{utxo}
|
||||
if err := fx.VerifyOperation(tx, op, cred, utxos); err == nil {
|
||||
t.Fatalf("VerifyOperation should have errored due to a wrong unique id")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFxVerifyTransferOperationWrongBytes(t *testing.T) {
|
||||
vm := secp256k1fx.TestVM{
|
||||
CLK: new(timer.Clock),
|
||||
Code: codec.NewDefault(),
|
||||
Log: logging.NoLog{},
|
||||
}
|
||||
date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC)
|
||||
vm.CLK.Set(date)
|
||||
|
||||
fx := Fx{}
|
||||
if err := fx.Initialize(&vm); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tx := &secp256k1fx.TestTx{
|
||||
Bytes: txBytes,
|
||||
}
|
||||
cred := &Credential{Credential: secp256k1fx.Credential{
|
||||
Sigs: [][crypto.SECP256K1RSigLen]byte{
|
||||
sigBytes,
|
||||
},
|
||||
}}
|
||||
utxo := &TransferOutput{
|
||||
GroupID: 1,
|
||||
Payload: []byte{2},
|
||||
OutputOwners: secp256k1fx.OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
},
|
||||
},
|
||||
}
|
||||
op := &TransferOperation{
|
||||
Input: secp256k1fx.Input{
|
||||
SigIndices: []uint32{0},
|
||||
},
|
||||
Output: TransferOutput{
|
||||
GroupID: 1,
|
||||
Payload: []byte{3},
|
||||
OutputOwners: secp256k1fx.OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.ShortEmpty,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
utxos := []interface{}{utxo}
|
||||
if err := fx.VerifyOperation(tx, op, cred, utxos); err == nil {
|
||||
t.Fatalf("VerifyOperation should have errored due to the wrong hash being produced")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFxVerifyOperationUnknownOperation(t *testing.T) {
|
||||
vm := secp256k1fx.TestVM{
|
||||
CLK: new(timer.Clock),
|
||||
Code: codec.NewDefault(),
|
||||
Log: logging.NoLog{},
|
||||
}
|
||||
date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC)
|
||||
vm.CLK.Set(date)
|
||||
|
||||
fx := Fx{}
|
||||
if err := fx.Initialize(&vm); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tx := &secp256k1fx.TestTx{
|
||||
Bytes: txBytes,
|
||||
}
|
||||
cred := &Credential{Credential: secp256k1fx.Credential{
|
||||
Sigs: [][crypto.SECP256K1RSigLen]byte{
|
||||
sigBytes,
|
||||
},
|
||||
}}
|
||||
utxo := &TransferOutput{
|
||||
GroupID: 1,
|
||||
Payload: []byte{2},
|
||||
OutputOwners: secp256k1fx.OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
utxos := []interface{}{utxo}
|
||||
if err := fx.VerifyOperation(tx, nil, cred, utxos); err == nil {
|
||||
t.Fatalf("VerifyOperation should have errored due to an unknown operation")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFxVerifyTransfer(t *testing.T) {
|
||||
vm := secp256k1fx.TestVM{
|
||||
CLK: new(timer.Clock),
|
||||
Code: codec.NewDefault(),
|
||||
Log: logging.NoLog{},
|
||||
}
|
||||
date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC)
|
||||
vm.CLK.Set(date)
|
||||
|
||||
fx := Fx{}
|
||||
if err := fx.Initialize(&vm); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := fx.VerifyTransfer(nil, nil, nil, nil); err == nil {
|
||||
t.Fatalf("this Fx doesn't support transfers")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package nftfx
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/ava-labs/gecko/vms/components/verify"
|
||||
"github.com/ava-labs/gecko/vms/secp256k1fx"
|
||||
)
|
||||
|
||||
var (
|
||||
errNilMintOperation = errors.New("nil mint operation")
|
||||
)
|
||||
|
||||
// MintOperation ...
|
||||
type MintOperation struct {
|
||||
MintInput secp256k1fx.Input `serialize:"true"`
|
||||
GroupID uint32 `serialize:"true"`
|
||||
Payload []byte `serialize:"true"`
|
||||
Outputs []*secp256k1fx.OutputOwners `serialize:"true"`
|
||||
}
|
||||
|
||||
// Outs ...
|
||||
func (op *MintOperation) Outs() []verify.Verifiable {
|
||||
outs := []verify.Verifiable{}
|
||||
for _, out := range op.Outputs {
|
||||
outs = append(outs, &TransferOutput{
|
||||
GroupID: op.GroupID,
|
||||
Payload: op.Payload,
|
||||
OutputOwners: *out,
|
||||
})
|
||||
}
|
||||
return outs
|
||||
}
|
||||
|
||||
// Verify ...
|
||||
func (op *MintOperation) Verify() error {
|
||||
switch {
|
||||
case op == nil:
|
||||
return errNilMintOperation
|
||||
case len(op.Payload) > MaxPayloadSize:
|
||||
return errPayloadTooLarge
|
||||
}
|
||||
|
||||
for _, out := range op.Outputs {
|
||||
if err := out.Verify(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return op.MintInput.Verify()
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package nftfx
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/ava-labs/gecko/vms/secp256k1fx"
|
||||
)
|
||||
|
||||
func TestMintOperationVerifyNil(t *testing.T) {
|
||||
op := (*MintOperation)(nil)
|
||||
if err := op.Verify(); err == nil {
|
||||
t.Fatalf("nil operation should have failed verification")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMintOperationVerifyTooLargePayload(t *testing.T) {
|
||||
op := MintOperation{
|
||||
Payload: make([]byte, MaxPayloadSize+1),
|
||||
}
|
||||
if err := op.Verify(); err == nil {
|
||||
t.Fatalf("operation should have failed verification")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMintOperationVerifyInvalidOutput(t *testing.T) {
|
||||
op := MintOperation{
|
||||
Outputs: []*secp256k1fx.OutputOwners{&secp256k1fx.OutputOwners{
|
||||
Threshold: 1,
|
||||
}},
|
||||
}
|
||||
if err := op.Verify(); err == nil {
|
||||
t.Fatalf("operation should have failed verification")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMintOperationOuts(t *testing.T) {
|
||||
op := MintOperation{
|
||||
Outputs: []*secp256k1fx.OutputOwners{&secp256k1fx.OutputOwners{}},
|
||||
}
|
||||
if outs := op.Outs(); len(outs) != 1 {
|
||||
t.Fatalf("Wrong number of outputs returned")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package nftfx
|
||||
|
||||
import (
|
||||
"github.com/ava-labs/gecko/vms/secp256k1fx"
|
||||
)
|
||||
|
||||
// MintOutput ...
|
||||
type MintOutput struct {
|
||||
GroupID uint32 `serialize:"true"`
|
||||
secp256k1fx.OutputOwners `serialize:"true"`
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package nftfx
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/ava-labs/gecko/vms/components/verify"
|
||||
"github.com/ava-labs/gecko/vms/secp256k1fx"
|
||||
)
|
||||
|
||||
var (
|
||||
errNilTransferOperation = errors.New("nil transfer operation")
|
||||
)
|
||||
|
||||
// TransferOperation ...
|
||||
type TransferOperation struct {
|
||||
Input secp256k1fx.Input `serialize:"true"`
|
||||
Output TransferOutput `serialize:"true"`
|
||||
}
|
||||
|
||||
// Outs ...
|
||||
func (op *TransferOperation) Outs() []verify.Verifiable {
|
||||
return []verify.Verifiable{&op.Output}
|
||||
}
|
||||
|
||||
// Verify ...
|
||||
func (op *TransferOperation) Verify() error {
|
||||
switch {
|
||||
case op == nil:
|
||||
return errNilTransferOperation
|
||||
default:
|
||||
return verify.All(&op.Input, &op.Output)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package nftfx
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/ava-labs/gecko/vms/secp256k1fx"
|
||||
)
|
||||
|
||||
func TestTransferOperationVerifyNil(t *testing.T) {
|
||||
op := (*TransferOperation)(nil)
|
||||
if err := op.Verify(); err == nil {
|
||||
t.Fatalf("nil operation should have failed verification")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTransferOperationInvalid(t *testing.T) {
|
||||
op := TransferOperation{Input: secp256k1fx.Input{
|
||||
SigIndices: []uint32{1, 0},
|
||||
}}
|
||||
if err := op.Verify(); err == nil {
|
||||
t.Fatalf("operation should have failed verification")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTransferOperationOuts(t *testing.T) {
|
||||
op := TransferOperation{
|
||||
Output: TransferOutput{},
|
||||
}
|
||||
if outs := op.Outs(); len(outs) != 1 {
|
||||
t.Fatalf("Wrong number of outputs returned")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package nftfx
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/ava-labs/gecko/vms/secp256k1fx"
|
||||
)
|
||||
|
||||
const (
|
||||
// MaxPayloadSize is the maximum size that can be placed into a payload
|
||||
MaxPayloadSize = 1 << 10
|
||||
)
|
||||
|
||||
var (
|
||||
errNilTransferOutput = errors.New("nil transfer output")
|
||||
errPayloadTooLarge = errors.New("payload too large")
|
||||
)
|
||||
|
||||
// TransferOutput ...
|
||||
type TransferOutput struct {
|
||||
GroupID uint32 `serialize:"true"`
|
||||
Payload []byte `serialize:"true"`
|
||||
secp256k1fx.OutputOwners `serialize:"true"`
|
||||
}
|
||||
|
||||
// Verify ...
|
||||
func (out *TransferOutput) Verify() error {
|
||||
switch {
|
||||
case out == nil:
|
||||
return errNilTransferOutput
|
||||
case len(out.Payload) > MaxPayloadSize:
|
||||
return errPayloadTooLarge
|
||||
default:
|
||||
return out.OutputOwners.Verify()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package nftfx
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/ava-labs/gecko/ids"
|
||||
"github.com/ava-labs/gecko/vms/secp256k1fx"
|
||||
)
|
||||
|
||||
func TestTransferOutputVerifyNil(t *testing.T) {
|
||||
to := (*TransferOutput)(nil)
|
||||
if err := to.Verify(); err == nil {
|
||||
t.Fatalf("TransferOutput.Verify should have errored on nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTransferOutputLargePayload(t *testing.T) {
|
||||
to := TransferOutput{
|
||||
Payload: make([]byte, MaxPayloadSize+1),
|
||||
}
|
||||
if err := to.Verify(); err == nil {
|
||||
t.Fatalf("TransferOutput.Verify should have errored on too large of a payload")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTransferOutputInvalidSecp256k1Output(t *testing.T) {
|
||||
to := TransferOutput{
|
||||
OutputOwners: secp256k1fx.OutputOwners{
|
||||
Addrs: []ids.ShortID{
|
||||
ids.ShortEmpty,
|
||||
ids.ShortEmpty,
|
||||
},
|
||||
},
|
||||
}
|
||||
if err := to.Verify(); err == nil {
|
||||
t.Fatalf("TransferOutput.Verify should have errored on too large of a payload")
|
||||
}
|
||||
}
|
|
@ -7,3 +7,9 @@ package secp256k1fx
|
|||
type Tx interface {
|
||||
UnsignedBytes() []byte
|
||||
}
|
||||
|
||||
// TestTx is a minimal implementation of a Tx
|
||||
type TestTx struct{ Bytes []byte }
|
||||
|
||||
// UnsignedBytes returns Bytes
|
||||
func (tx *TestTx) UnsignedBytes() []byte { return tx.Bytes }
|
||||
|
|
|
@ -15,3 +15,19 @@ type VM interface {
|
|||
Clock() *timer.Clock
|
||||
Logger() logging.Logger
|
||||
}
|
||||
|
||||
// TestVM is a minimal implementation of a VM
|
||||
type TestVM struct {
|
||||
CLK *timer.Clock
|
||||
Code codec.Codec
|
||||
Log logging.Logger
|
||||
}
|
||||
|
||||
// Clock returns CLK
|
||||
func (vm *TestVM) Clock() *timer.Clock { return vm.CLK }
|
||||
|
||||
// Codec returns Code
|
||||
func (vm *TestVM) Codec() codec.Codec { return vm.Code }
|
||||
|
||||
// Logger returns Log
|
||||
func (vm *TestVM) Logger() logging.Logger { return vm.Log }
|
||||
|
|
Loading…
Reference in New Issue