Skip to content

Commit

Permalink
alphabet: Add verify method
Browse files Browse the repository at this point in the history
There is no way to move NEO from the Alphabet contracts right now. This
can be needed for some migrations or fixes.

Proxy contract already had this method, so functionality is shared b/w
them.

Closes #386.

Signed-off-by: Leonard Lyubich <leonard@morphbits.io>
  • Loading branch information
cthulhu-rider committed Mar 11, 2024
1 parent 91962f2 commit 9e89a8e
Show file tree
Hide file tree
Showing 8 changed files with 40 additions and 25 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Changelog for NeoFS Contract
## [Unreleased]

### Added
- `verify` method for Alphabet contracts (#386)

### Updated

Expand Down
10 changes: 10 additions & 0 deletions common/ir.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,13 @@ func Multiaddress(n []interop.PublicKey, committee bool) []byte {

return contract.CreateMultisigAccount(threshold, n)
}

// ContainsAlphabetWitness checks whether carrier transaction contains either
// (2/3N + 1) or (N/2 + 1) valid multi-signature of the NeoFS Alphabet.
func ContainsAlphabetWitness() bool {
alphabet := neo.GetCommittee()
if runtime.CheckWitness(Multiaddress(alphabet, false)) {
return true
}
return runtime.CheckWitness(Multiaddress(alphabet, true))
}
2 changes: 1 addition & 1 deletion contracts/alphabet/config.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: "NeoFS Alphabet"
safemethods: ["gas", "neo", "name", "version"]
safemethods: ["gas", "neo", "name", "version", "verify"]
permissions:
- methods: ["update", "transfer", "vote"]
6 changes: 6 additions & 0 deletions contracts/alphabet/contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -340,3 +340,9 @@ func Name() string {
func Version() int {
return common.Version
}

// Verify checks whether carrier transaction contains either (2/3N + 1) or
// (N/2 + 1) valid multi-signature of the NeoFS Alphabet.
func Verify() bool {
return common.ContainsAlphabetWitness()
}
15 changes: 3 additions & 12 deletions contracts/proxy/contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"github.com/nspcc-dev/neo-go/pkg/interop/contract"
"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/native/neo"
"github.com/nspcc-dev/neo-go/pkg/interop/runtime"
"github.com/nspcc-dev/neofs-contract/common"
)
Expand Down Expand Up @@ -41,18 +40,10 @@ func Update(script []byte, manifest []byte, data any) {
runtime.Log("proxy contract updated")
}

// Verify method returns true if transaction contains valid multisignature of
// Alphabet nodes of the Inner Ring.
// Verify checks whether carrier transaction contains either (2/3N + 1) or
// (N/2 + 1) valid multi-signature of the NeoFS Alphabet.
func Verify() bool {
alphabet := neo.GetCommittee()
sig := common.Multiaddress(alphabet, false)

if !runtime.CheckWitness(sig) {
sig = common.Multiaddress(alphabet, true)
return runtime.CheckWitness(sig)
}

return true
return common.ContainsAlphabetWitness()
}

// Version returns the version of the contract.
Expand Down
5 changes: 5 additions & 0 deletions tests/alphabet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,3 +154,8 @@ func getAlphabetAcc(t *testing.T, e *neotest.Executor) *wallet.Account {

return multi.Single(0).Account()
}

func TestAlphabetVerify(t *testing.T) {
_, contract := newAlphabetInvoker(t, false)
testVerify(t, contract)
}
12 changes: 12 additions & 0 deletions tests/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,22 @@ package tests

import (
"math/rand"
"testing"

"github.com/nspcc-dev/neo-go/pkg/neotest"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
)

func randomBytes(n int) []byte {
a := make([]byte, n)
rand.Read(a) //nolint:staticcheck // SA1019: rand.Read has been deprecated since Go 1.20
return a
}

// tests contract's 'verify' method checking whether carrier transaction is
// signed by the NeoFS Alphabet.
func testVerify(t testing.TB, contract *neotest.ContractInvoker) {
const method = "verify"
contract.Invoke(t, stackitem.NewBool(true), method)
contract.WithSigners(contract.NewAccount(t)).Invoke(t, stackitem.NewBool(false), method)
}
14 changes: 2 additions & 12 deletions tests/proxy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (

"github.com/nspcc-dev/neo-go/pkg/neotest"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
)

const proxyPath = "../contracts/proxy"
Expand All @@ -29,15 +28,6 @@ func newProxyInvoker(t *testing.T) *neotest.ContractInvoker {
return e.CommitteeInvoker(ctrProxy.Hash)
}

func TestVerify(t *testing.T) {
e := newProxyInvoker(t)

const method = "verify"

e.Invoke(t, stackitem.NewBool(true), method)

notAlphabet := e.NewAccount(t)
cNotAlphabet := e.WithSigners(notAlphabet)

cNotAlphabet.Invoke(t, stackitem.NewBool(false), method)
func TestProxyVerify(t *testing.T) {
testVerify(t, newProxyInvoker(t))
}

0 comments on commit 9e89a8e

Please sign in to comment.