forked from TrueCloudLab/neoneo-go
rpcclient/notary: add OnNEP17PaymentData and an example
Update documentation as well to mention it and not mention outdated APIs. We can't link them yet, this will be done after the release.
This commit is contained in:
parent
4fb4f5a1ac
commit
6be9367f03
3 changed files with 104 additions and 6 deletions
|
@ -292,8 +292,10 @@ server via [`submitnotaryrequest` RPC call](./rpc.md#submitnotaryrequest-call).
|
|||
Note, that all parties must generate the same main transaction while fallbacks
|
||||
can differ.
|
||||
|
||||
To create a notary request, you can use [NeoGo RPC client](./rpc.md#Client). Follow
|
||||
the steps to create a signature request:
|
||||
To create a notary request, you can use [NeoGo RPC client](./rpc.md#Client). The
|
||||
procedure below uses only basic RPC client functions and show all of the notary
|
||||
request internals. You can use much simpler Actor interface in the notary
|
||||
subpackage with an example written in Go doc.
|
||||
|
||||
1. Prepare a list of signers with scopes for the main transaction (i.e. the
|
||||
transaction that signatures are being collected for, that will be `Signers`
|
||||
|
@ -307,8 +309,7 @@ the steps to create a signature request:
|
|||
Include Notary native contract in the list of signers with the following
|
||||
constraints:
|
||||
* Notary signer hash is the hash of a native Notary contract that can be fetched
|
||||
from
|
||||
[func (*Client) GetNativeContractHash](https://pkg.go.dev/github.com/nspcc-dev/neo-go@v0.97.2/pkg/rpcclient#Client.GetNativeContractHash).
|
||||
from the notary RPC client subpackage (notary.Hash)
|
||||
* A notary signer must have `None` scope.
|
||||
* A notary signer shouldn't be placed at the beginning of the signer list
|
||||
because Notary contract does not pay main transaction fees. Other positions
|
||||
|
@ -390,8 +391,7 @@ the steps to create a signature request:
|
|||
tries to push all associated fallbacks. Use the following rules to define
|
||||
`fallbackValidFor`:
|
||||
- `fallbackValidFor` shouldn't be more than `MaxNotValidBeforeDelta` value.
|
||||
- Use [func (*Client) GetMaxNotValidBeforeDelta](https://pkg.go.dev/github.com/nspcc-dev/neo-go@v0.97.2/pkg/rpcclient#Client.GetMaxNotValidBeforeDelta)
|
||||
to check `MaxNotValidBefore` value.
|
||||
- Use notary package's GetMaxNotValidBeforeDelta to check `MaxNotValidBefore` value.
|
||||
11. Construct a script for the fallback transaction. The script may do something useful,
|
||||
i.g. invoke method of a contract. However, if you don't need to perform anything
|
||||
special on fallback invocation, you can use simple `opcode.RET` script.
|
||||
|
|
|
@ -59,6 +59,15 @@ type Contract struct {
|
|||
actor ContractActor
|
||||
}
|
||||
|
||||
// OnNEP17PaymentData is the data set that is accepted by the notary contract
|
||||
// onNEP17Payment handler. It's mandatory for GAS tranfers to this contract.
|
||||
type OnNEP17PaymentData struct {
|
||||
// Account can be nil, in this case transfer sender (from) account is used.
|
||||
Account *util.Uint160
|
||||
// Till specifies the deposit lock time (in blocks).
|
||||
Till uint32
|
||||
}
|
||||
|
||||
// Hash stores the hash of the native Notary contract.
|
||||
var Hash = state.CreateNativeContractHash(nativenames.Notary)
|
||||
|
||||
|
|
89
pkg/rpcclient/notary/doc_test.go
Normal file
89
pkg/rpcclient/notary/doc_test.go
Normal file
|
@ -0,0 +1,89 @@
|
|||
package notary_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"math/big"
|
||||
"time"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient"
|
||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/actor"
|
||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/gas"
|
||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/notary"
|
||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/policy"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/vmstate"
|
||||
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
||||
)
|
||||
|
||||
func ExampleActor() {
|
||||
// No error checking done at all, intentionally.
|
||||
w, _ := wallet.NewWalletFromFile("somewhere")
|
||||
defer w.Close()
|
||||
// We assume there are two accounts in the wallet --- one is a simple signature
|
||||
// account and another one is committee account. The first one will send notary
|
||||
// requests, while committee signatures need to be collected.
|
||||
|
||||
// Create an RPC client.
|
||||
c, _ := rpcclient.New(context.Background(), "url", rpcclient.Options{})
|
||||
|
||||
// An actor for the first account.
|
||||
single, _ := actor.NewSimple(c, w.Accounts[0])
|
||||
|
||||
// Transfer some GAS to the Notary contract to be able to send notary requests
|
||||
// from the first account.
|
||||
gasSingle := gas.New(single)
|
||||
txid, vub, _ := gasSingle.Transfer(single.Sender(), notary.Hash, big.NewInt(10_0000_0000), notary.OnNEP17PaymentData{Till: 10000000})
|
||||
|
||||
var depositOK bool
|
||||
// Wait for transaction to be persisted, either it gets in and we get
|
||||
// an application log with some result or it expires.
|
||||
for height, err := c.GetBlockCount(); err == nil && height <= vub; height, err = c.GetBlockCount() {
|
||||
appLog, err := c.GetApplicationLog(txid, nil)
|
||||
// We can't separate "application log missing" from other errors at the moment, see #2248.
|
||||
if err != nil {
|
||||
time.Sleep(5 * time.Second)
|
||||
continue
|
||||
}
|
||||
if len(appLog.Executions) == 1 && appLog.Executions[0].VMState == vmstate.Halt {
|
||||
depositOK = true
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
if !depositOK {
|
||||
panic("deposit failed")
|
||||
}
|
||||
|
||||
var opts notary.ActorOptions
|
||||
// Add high priority attribute, we gonna be making committee-signed transactions anyway.
|
||||
opts.MainAttributes = []transaction.Attribute{{Type: transaction.HighPriority}}
|
||||
|
||||
// Create an Actor with the simple account used for paying fees and committee
|
||||
// signature to be collected.
|
||||
multi, _ := notary.NewTunedActor(c, []actor.SignerAccount{{
|
||||
// Sender, regular account with None scope.
|
||||
Signer: transaction.Signer{
|
||||
Account: w.Accounts[0].ScriptHash(),
|
||||
Scopes: transaction.None,
|
||||
},
|
||||
Account: w.Accounts[0],
|
||||
}, {
|
||||
// Commmitee.
|
||||
Signer: transaction.Signer{
|
||||
Account: w.Accounts[1].ScriptHash(),
|
||||
Scopes: transaction.CalledByEntry,
|
||||
},
|
||||
Account: w.Accounts[1],
|
||||
}}, opts)
|
||||
|
||||
// Use the Policy contract to perform something requiring committee signature.
|
||||
policyContract := policy.New(multi)
|
||||
|
||||
// Wrap a transaction to set storage price into a notary request. Fallback will
|
||||
// be create automatically and all appropriate attributes will be added to both
|
||||
// transactions.
|
||||
mainTx, fbTx, vub, _ := multi.Notarize(policyContract.SetStoragePriceTransaction(10))
|
||||
_ = mainTx
|
||||
_ = fbTx
|
||||
_ = vub
|
||||
}
|
Loading…
Reference in a new issue