From 5372329d4972f6d3674edb0b4da69a51bd4fdc30 Mon Sep 17 00:00:00 2001 From: Alex Vanin Date: Tue, 20 Apr 2021 17:44:36 +0300 Subject: [PATCH] [#74] neofs: Pay withdraw fee to processing contract Processing contracts pays for cheque that transfer assets back to the user, so user should transfer some fee to this contract. Withdraw fee defined in NeoFS global configuration. Signed-off-by: Alex Vanin --- neofs/neofs_contract.go | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/neofs/neofs_contract.go b/neofs/neofs_contract.go index 9f9bb08..0bb9545 100644 --- a/neofs/neofs_contract.go +++ b/neofs/neofs_contract.go @@ -53,12 +53,15 @@ type ( const ( candidateFeeConfigKey = "InnerRingCandidateFee" + withdrawFeeConfigKey = "WithdrawFee" version = 3 alphabetKey = "alphabet" candidatesKey = "candidates" + processingContractKey = "processingScriptHash" + publicKeySize = 33 maxBalanceAmount = 9000 // Max integer of Fixed12 in JSON bound (2**53-1) @@ -72,7 +75,7 @@ var ( ) // Init set up initial alphabet node keys. -func Init(owner interop.PublicKey, args []interop.PublicKey) bool { +func Init(owner, addrProc interop.Hash160, args []interop.PublicKey) bool { ctx := storage.GetContext() if !common.HasUpdateAccess(ctx) { @@ -85,6 +88,10 @@ func Init(owner interop.PublicKey, args []interop.PublicKey) bool { panic("neofs: at least one alphabet key must be provided") } + if len(addrProc) != 20 { + panic("neofs: incorrect length of contract script hash") + } + for i := 0; i < len(args); i++ { pub := args[i] if len(pub) != publicKeySize { @@ -98,6 +105,7 @@ func Init(owner interop.PublicKey, args []interop.PublicKey) bool { common.SetSerialized(ctx, candidatesKey, []common.IRNode{}) storage.Put(ctx, common.OwnerKey, owner) + storage.Put(ctx, processingContractKey, addrProc) runtime.Log("neofs: contract initialized") @@ -246,7 +254,7 @@ func Deposit(from interop.Hash160, amount int, rcv interop.Hash160) bool { } // Withdraw initialize gas asset withdraw from NeoFS balance. -func Withdraw(user []byte, amount int) bool { +func Withdraw(user interop.Hash160, amount int) bool { if !runtime.CheckWitness(user) { panic("withdraw: you should be the owner of the wallet") } @@ -259,9 +267,20 @@ func Withdraw(user []byte, amount int) bool { panic("withdraw: out of max amount limit") } - amount = amount * 100000000 + // transfer fee to proxy contract to pay cheque invocation + ctx := storage.GetContext() + fee := getConfig(ctx, withdrawFeeConfigKey).(int) + processingAddr := storage.Get(ctx, processingContractKey).(interop.Hash160) + transferred := gas.Transfer(user, processingAddr, fee, []byte{}) + if !transferred { + panic("withdraw: failed to transfer withdraw fee, aborting") + } + + // notify alphabet nodes + amount = amount * 100000000 tx := runtime.GetScriptContainer() + runtime.Notify("Withdraw", user, amount, tx.Hash) return true