80 lines
2.5 KiB
Go
80 lines
2.5 KiB
Go
package neofs
|
|
|
|
import (
|
|
"git.marketally.com/tutus-one/tutus-chain/pkg/interop"
|
|
"git.marketally.com/tutus-one/tutus-chain/pkg/interop/native/oracle"
|
|
"git.marketally.com/tutus-one/tutus-chain/pkg/interop/native/std"
|
|
"git.marketally.com/tutus-one/tutus-chain/pkg/interop/runtime"
|
|
"git.marketally.com/tutus-one/tutus-chain/pkg/interop/storage"
|
|
)
|
|
|
|
const (
|
|
ownerKey = "owner"
|
|
objectKey = "object"
|
|
)
|
|
|
|
// _deploy is called after contract deployment or update. It initializes the
|
|
// contract owner from the deployment data.
|
|
func _deploy(data any, isUpdate bool) { // nolint: unused
|
|
if isUpdate {
|
|
return
|
|
}
|
|
owner := data.(interop.Hash160)
|
|
if len(owner) != interop.Hash160Len {
|
|
panic("invalid owner address")
|
|
}
|
|
storage.Put(storage.GetContext(), ownerKey, owner)
|
|
}
|
|
|
|
// GetObject returns the NeoFS object stored in the contract storage.
|
|
func GetObject() []byte {
|
|
return storage.Get(storage.GetReadOnlyContext(), objectKey).([]byte)
|
|
}
|
|
|
|
// SaveObject requests a NeoFS object specified by the container ID (cid) and
|
|
// object ID (oid) using the Oracle service. The object data will be saved to
|
|
// the contract storage once the oracle response is received. Only the contract
|
|
// owner can call this method.
|
|
func SaveObject(cid, oid string) {
|
|
checkAccess()
|
|
|
|
url := "neofs:" + cid + "/" + oid
|
|
oracle.Request(url, nil, "saveObjectCB", nil, 15*oracle.MinimumResponseGas)
|
|
}
|
|
|
|
// SaveObjectCB is called by the Oracle native contract when the NeoFS object
|
|
// request is finished. It validates that the caller is the oracle contract,
|
|
// checks the response code, and saves the object data to contract storage.
|
|
func SaveObjectCB(url string, data any, code int, result []byte) {
|
|
if string(runtime.GetCallingScriptHash()) != oracle.Hash {
|
|
panic("called by non-oracle contract")
|
|
}
|
|
if code != oracle.Success {
|
|
panic("request failed for " + url + " with code " + std.Itoa(code, 10))
|
|
}
|
|
|
|
storage.Put(storage.GetContext(), objectKey, result)
|
|
}
|
|
|
|
// DeleteObject removes the stored NeoFS object from the contract storage.
|
|
// Only the contract owner can call this method.
|
|
func DeleteObject() {
|
|
checkAccess()
|
|
|
|
storage.Delete(storage.GetContext(), objectKey)
|
|
}
|
|
|
|
// Owner returns the contract owner's script hash.
|
|
func Owner() interop.Hash160 {
|
|
return storage.Get(storage.GetReadOnlyContext(), ownerKey).(interop.Hash160)
|
|
}
|
|
|
|
// checkAccess verifies that the contract owner has witnessed the transaction.
|
|
// It panics if the witness check fails.
|
|
func checkAccess() {
|
|
owner := storage.Get(storage.GetReadOnlyContext(), ownerKey).(interop.Hash160)
|
|
if !runtime.CheckWitness(owner) {
|
|
panic("not allowed user")
|
|
}
|
|
}
|