neo-go/internal/contracts/contracts.go
Roman Khimov da2db74bc9 contracts: decipher oracle test contract
Make it a proper Go contract, opcodes are fun until you want to change
something in them. Part of #2412.
2022-08-10 19:02:36 +03:00

105 lines
3.9 KiB
Go

package contracts
import (
"encoding/json"
"errors"
"fmt"
"os"
"path/filepath"
"testing"
"github.com/nspcc-dev/neo-go/pkg/core/state"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/nef"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/stretchr/testify/require"
)
var (
helper1ContractNEFPath = filepath.Join("management_helper", "management_helper1.nef")
helper1ContractManifestPath = filepath.Join("management_helper", "management_helper1.manifest.json")
helper2ContractNEFPath = filepath.Join("management_helper", "management_helper2.nef")
helper2ContractManifestPath = filepath.Join("management_helper", "management_helper2.manifest.json")
oracleContractModPath = "oracle_contract"
oracleContractYAMLPath = filepath.Join(oracleContractModPath, "oracle.yml")
oracleContractNEFPath = filepath.Join(oracleContractModPath, "oracle.nef")
oracleContractManifestPath = filepath.Join(oracleContractModPath, "oracle.manifest.json")
)
// GetTestContractState reads 2 pre-compiled contracts generated by
// TestGenerateHelperContracts, second of which is allowed to call the first.
func GetTestContractState(t *testing.T, pathToInternalContracts string, id1, id2 int32, sender2 util.Uint160) (*state.Contract, *state.Contract) {
errNotFound := errors.New("auto-generated oracle contract is not found, use TestGenerateHelperContracts to regenerate")
neBytes, err := os.ReadFile(filepath.Join(pathToInternalContracts, helper1ContractNEFPath))
require.NoError(t, err, fmt.Errorf("nef1: %w", errNotFound))
ne, err := nef.FileFromBytes(neBytes)
require.NoError(t, err)
mBytes, err := os.ReadFile(filepath.Join(pathToInternalContracts, helper1ContractManifestPath))
require.NoError(t, err, fmt.Errorf("manifest1: %w", errNotFound))
m := &manifest.Manifest{}
err = json.Unmarshal(mBytes, m)
require.NoError(t, err)
cs1 := &state.Contract{
ContractBase: state.ContractBase{
NEF: ne,
Manifest: *m,
ID: id1,
},
}
neBytes, err = os.ReadFile(filepath.Join(pathToInternalContracts, helper2ContractNEFPath))
require.NoError(t, err, fmt.Errorf("nef2: %w", errNotFound))
ne, err = nef.FileFromBytes(neBytes)
require.NoError(t, err)
mBytes, err = os.ReadFile(filepath.Join(pathToInternalContracts, helper2ContractManifestPath))
require.NoError(t, err, fmt.Errorf("manifest2: %w", errNotFound))
m = &manifest.Manifest{}
err = json.Unmarshal(mBytes, m)
require.NoError(t, err)
// Retrieve hash of the first contract from the permissions of the second contract.
require.Equal(t, 1, len(m.Permissions))
require.Equal(t, manifest.PermissionHash, m.Permissions[0].Contract.Type)
cs1.Hash = m.Permissions[0].Contract.Hash()
cs2 := &state.Contract{
ContractBase: state.ContractBase{
NEF: ne,
Manifest: *m,
ID: id2,
Hash: state.CreateContractHash(sender2, ne.Checksum, m.Name),
},
}
return cs1, cs2
}
// GetOracleContractState reads pre-compiled oracle contract generated by
// TestGenerateHelperContracts and returns its state.
func GetOracleContractState(t *testing.T, pathToInternalContracts string, sender util.Uint160, id int32) *state.Contract {
errNotFound := errors.New("auto-generated oracle contract is not found, use TestGenerateHelperContracts to regenerate")
neBytes, err := os.ReadFile(filepath.Join(pathToInternalContracts, oracleContractNEFPath))
require.NoError(t, err, fmt.Errorf("nef: %w", errNotFound))
ne, err := nef.FileFromBytes(neBytes)
require.NoError(t, err)
mBytes, err := os.ReadFile(filepath.Join(pathToInternalContracts, oracleContractManifestPath))
require.NoError(t, err, fmt.Errorf("manifest: %w", errNotFound))
m := &manifest.Manifest{}
err = json.Unmarshal(mBytes, m)
require.NoError(t, err)
return &state.Contract{
ContractBase: state.ContractBase{
NEF: ne,
Hash: state.CreateContractHash(sender, ne.Checksum, m.Name),
Manifest: *m,
ID: id,
},
}
}