diff --git a/Makefile b/Makefile index aec885e..e4fe89e 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ all: sidechain mainnet sidechain: alphabet morph alphabet_sc = alphabet -morph_sc = audit balance container neofsid netmap reputation +morph_sc = audit balance container neofsid netmap proxy reputation mainnet_sc = neofs define sc_template diff --git a/common/ir.go b/common/ir.go index b27e476..98c3d0a 100644 --- a/common/ir.go +++ b/common/ir.go @@ -7,7 +7,10 @@ import ( "github.com/nspcc-dev/neo-go/pkg/interop/storage" ) -const irListMethod = "innerRingList" +const ( + irListMethod = "innerRingList" + multiaddrMethod = "multiaddress" +) type IRNode struct { PublicKey []byte @@ -39,3 +42,17 @@ func InnerRingListViaStorage(ctx storage.Context, key interface{}) []IRNode { func InnerRingList(sc interop.Hash160) []IRNode { return contract.Call(sc, irListMethod, contract.ReadOnly).([]IRNode) } + +// InnerRingMultiAddressViaStorage returns multiaddress of inner ring public +// keys by invoking netmap contract, which scripthash stored in the contract +// storage by the key `key`. +func InnerRingMultiAddressViaStorage(ctx storage.Context, key interface{}) []byte { + sc := storage.Get(ctx, key).([]byte) + return InnerRingMultiAddress(sc) +} + +// InnerRingMultiAddress returns multiaddress of inner ring public keys by +// invoking netmap contract. +func InnerRingMultiAddress(sc interop.Hash160) []byte { + return contract.Call(sc, multiaddrMethod, contract.ReadOnly).([]byte) +} diff --git a/proxy/config.yml b/proxy/config.yml new file mode 100644 index 0000000..6b64aa3 --- /dev/null +++ b/proxy/config.yml @@ -0,0 +1 @@ +name: "NeoFS Notary Proxy" diff --git a/proxy/proxy_contract.go b/proxy/proxy_contract.go new file mode 100644 index 0000000..9bceb58 --- /dev/null +++ b/proxy/proxy_contract.go @@ -0,0 +1,65 @@ +package proxycontract + +import ( + "github.com/nspcc-dev/neo-go/pkg/interop" + "github.com/nspcc-dev/neo-go/pkg/interop/native/gas" + "github.com/nspcc-dev/neo-go/pkg/interop/native/management" + "github.com/nspcc-dev/neo-go/pkg/interop/runtime" + "github.com/nspcc-dev/neo-go/pkg/interop/storage" + "github.com/nspcc-dev/neofs-contract/common" +) + +const ( + version = 1 + + netmapContractKey = "netmapScriptHash" +) + +var ctx storage.Context + +func init() { + ctx = storage.GetContext() +} + +func OnNEP17Payment(from interop.Hash160, amount int, data interface{}) { + caller := runtime.GetCallingScriptHash() + if !common.BytesEqual(caller, []byte(gas.Hash)) { + panic("onNEP17Payment: alphabet contract accepts GAS only") + } +} + +func Init(owner interop.Hash160, addrNetmap []byte) { + if !common.HasUpdateAccess(ctx) { + panic("only owner can reinitialize contract") + } + + if len(addrNetmap) != 20 { + panic("init: incorrect length of contract script hash") + } + + storage.Put(ctx, common.OwnerKey, owner) + storage.Put(ctx, netmapContractKey, addrNetmap) + + runtime.Log("proxy contract initialized") +} + +func Migrate(script []byte, manifest []byte) bool { + if !common.HasUpdateAccess(ctx) { + runtime.Log("only owner can update contract") + return false + } + + management.Update(script, manifest) + runtime.Log("proxy contract updated") + + return true +} + +func Verify() bool { + sig := common.InnerRingMultiAddressViaStorage(ctx, netmapContractKey) + return runtime.CheckWitness(sig) +} + +func Version() int { + return version +}