大家好我真的需要帮助,我有一个域名注册智能合约,文件名为“name.pact”和一个名为“name.repl”的REPL文件。 这是文件结构:
--->smartcontract
-->root
-->coin-v5.pact
-->fungible-v2.pact
-->fungible-xchain-v1.pact
-->name.pact
-->name.repl
这是我的名字.pact文件
(namespace 'free)
(define-keyset "free.domain-admin-gov-keyset" (read-keyset 'domain-admin-gov-keyset))
(module testingdomain GOVERNANCE
; --------------------------------------------------------------------------
; Schemas and Tables
; subdomain-schema
(defschema subdomain
name:string
address:string
)
;define names schema
(defschema names
owner:string
lastPrice:decimal
subdomains:list
)
;define name map schema
(defschema name-map
address:string
top-level-name:string
)
;define address map schema
(defschema address-map
name:string
top-level-name:string
)
;define sales schema
(defschema sales
price:decimal
sellable:bool
)
(deftable names-table:{names})
(deftable name-map-table:{name-map})
(deftable address-map-table:{address-map})
(deftable sales-table:{sales})
; --------------------------------------------------------------------------
; Constants
(defconst BASE_ONEYEAR_PRICE 1.0)
(defconst BASE_TWOYEAR_PRICE (* (* BASE_ONEYEAR_PRICE 2) 0.95))
(defconst SUBDOMAIN_PRICE 3.0)
(defconst UPDATE_PRICE 0.5)
(defconst SELL_FEE_PERCENTAGE 5.0)
(defconst EXPIRATION_GRACE_PERIOD 31)
(defconst VAULT_ACCOUNT "k:36990b871267ec4532551e505260806d7f39378cebb5ea2c998c80301c5a100f")
(defconst ALLOWED_CHARS:list ["-", "_", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"])
; --------------------------------------------------------------------------
; Utils
(defun curr-time:time ()
@doc "Returns current chain's block-time in time type"
(at 'block-time (chain-data)))
; --------------------------------------------------------------------------
; Capabilities
(use coin [ details transfer ])
(defcap GOVERNANCE ()
"Module governance capability that only allows the admin to update this module"
;; Check if the tx was signed with the provided keyset, fail if not
(enforce-keyset "free.doamin-admin-gov-keyset"))
(defcap ACCOUNT_GUARD (account)
(enforce-guard (at 'guard (coin.details account)))
)
(defcap NAME_AVAILABLE (name:string)
@doc "Validate if the name is available "
(with-default-read names-table name
{ "expiryDate": (add-time (curr-time) (days (* -1 EXPIRATION_GRACE_PERIOD))) }
{ "expiryDate":= expiryDate }
(enforce (>= (curr-time) (add-time expiryDate (days EXPIRATION_GRACE_PERIOD))) "Name not available")
)
)
(defcap NAME_UPSERT (name:string)
"New name has been added or updated"
@event
true
)
(defcap ITEM_SOLD (name:string prevOwner:string newOwner:string price:decimal)
"An item has been sold"
@event
true
)
(defcap SALE_STATUS_UPDATED (name:string)
"An item has been put up for and removed from sale"
@event
true
)
(defcap MAPPING () true)
; --------------------------------------------------------------------------
; Functions
(defun enforce-domain (name:string)
(enforce (= ".kda" (take -4 name)) "Domain should be .kda")
)
(defun strip-domain (name:string)
(drop -4 name)
)
(defun enforce-name-is-valid (name:string)
(enforce (<= (length name) 35) "Maximum 35 characters allowed in name")
(enforce (!= name "") "Name should not be empty")
(let*
(
(validate-character (lambda (character)
(enforce (= true (contains character ALLOWED_CHARS)) "No forbidden chars allowed")
))
)
(map (validate-character) (str-to-list name))
)
)
(defun enforce-address-is-valid (address: string)
(enforce-one "Only k: and w: accounts are supported" [
(enforce (= (take 2 address) "k:") "k:account")
(enforce (= (take 2 address) "w:") "w:account")
])
)
(defun enforce-days-is-valid (nrDays:integer)
(enforce-one "Invalid days" [
(enforce (= nrDays 365) "One year")
(enforce (= nrDays 730) "Two years")
])
)
(defun enforce-address-not-in-use (address: string)
(with-default-read address-map-table address
{
"name" : "",
"top-level-name" : ""
}
{
"name" := name,
"top-level-name" := toplevelname
}
(with-default-read names-table toplevelname
{ "expiryDate": (add-time (curr-time) (days (* -1 EXPIRATION_GRACE_PERIOD))) }
{ "expiryDate":= expiryDate }
(enforce-one "Address already in use" [
(enforce (= name "") "Name is an empty string, so mapping doesn't exist")
(enforce (>= (curr-time) (add-time expiryDate (days EXPIRATION_GRACE_PERIOD))) "Address map exists but domain has expired")
])
)
)
)
(defun get-price (days:integer)
(if (= days 365) BASE_ONEYEAR_PRICE BASE_TWOYEAR_PRICE)
)
(defun set-mappings (fqn:string toplevelname:string address:string)
(require-capability (MAPPING))
(write name-map-table fqn {
"address": address,
"top-level-name": toplevelname
})
(write address-map-table address {
"name": fqn,
"top-level-name": toplevelname
})
)
(defun remove-mappings (fqn:string)
(require-capability (MAPPING))
(with-read name-map-table fqn
{
"address":= address
}
(write name-map-table fqn {
"address": "",
"top-level-name": ""
})
(write address-map-table address {
"name": "",
"top-level-name": ""
})
)
)
(defun register (owner:string address:string name:string nrDays:integer)
(enforce-domain name)
(enforce-name-is-valid (strip-domain name))
(enforce-days-is-valid nrDays)
(enforce-address-is-valid address)
(enforce-address-not-in-use address)
(with-capability (NAME_AVAILABLE name)
(with-capability (ACCOUNT_GUARD owner)
(with-capability (NAME_UPSERT name)
(with-capability (MAPPING)
(coin.transfer owner VAULT_ACCOUNT (get-price nrDays))
; Clear existing subdomain mapping if available
(with-default-read names-table name
{ "subdomains": [] }
{ "subdomains":= subdomains }
(map (remove-mappings) subdomains)
)
; write name information
(write names-table name {
"owner": owner,
"lastPrice": (get-price nrDays),
"expiryDate": (add-time (curr-time) (days nrDays)),
"subdomains": []
})
; Set mappings
(set-mappings name name address)
; Clear open sell order if available
(with-default-read sales-table name
{ "sellable": false }
{ "sellable":= sellable }
(if sellable (update sales-table name { "sellable": false }) true)
)
))))
)
)
这是我的名字.repl文件
;; begin-tx and commit-tx simulate a transaction
(begin-tx "Load modules")
;; set transaction JSON data
(env-data {
;; Here we set the required keysets.
;; Note:
;; - in a real transaction, `admin-key` would be a public key
;; - "keys-all" is a built-in predicate that specifies all keys are needed to sign a tx,
;; in this case we only set one key
'domain-admin-gov-keyset: { "keys": ["domain-admin-gov-keyset"], "pred": "keys-all" },
'alice-keyset: { "keys": ["alice-key"], "pred": "keys-all" },
'bob-keyset: { "keys": ["bob-key"], "pred": "keys-all" },
'namespace-keyset: { "keys": [ ], "pred": "keys-all" },
;; Upgrade key is set to false because we are deploying the modules
'upgrade: false
})
(define-namespace "free" (read-keyset "namespace-keyset") (read-keyset "namespace-keyset"))
;; load fungible-v2 interface
(load "root/fungible-v2.pact")
;; load fungible-xchain-v1 interace
(load "root/fungible-xchain-v1.pact")
;; load coin module
(load "root/coin-v5.pact")
;; create coin module tables
(create-table coin.coin-table)
(create-table coin.allocation-table)
;; load election module
(load "name.pact")
;; commit the transaction
(commit-tx)
(begin-tx "Create KDA accounts")
(coin.create-account "k:36990b871267ec4532551e505260806d7f39378cebb5ea2c998c80301c5a100f" (read-keyset "domain-admin-gov-keyset"))
;; create "alice" KDA account
(coin.create-account "alice" (read-keyset "alice-keyset"))
;; create "bob" KDA account
(coin.create-account "bob" (read-keyset "bob-keyset"))
(env-data {'k:["alice-key"]})
(test-capability (coin.CREDIT "alice"))
(coin.credit "alice" (read-keyset 'k) 10000.0)
(commit-tx)
(begin-tx "Try buying a domain name")
(use free.testingdomain)
(env-sigs [{ "key": "alice-key", "caps": [(coin.TRANSFER "alice" "k:36990b871267ec4532551e505260806d7f39378cebb5ea2c998c80301c5a100f" 1.0), (free.testingdomain.ACCOUNT_GUARD "alice")]}])
(register "alice" "k:2cf3e52a1e9e961257599a5155cc5ef3e836fc8f70b7edf867cfbf45a07d612d" "elijahd.kda" 365)
(expect "Info details of domain name")
(commit-tx)
运行name.repl文件 契约>(加载“名称”)
在 name.repl 文件中,我试图从智能合约测试 register 函数,它总是以抛出错误告终。
运行name.repl文件来测试智能合约 契约(加载“name.repl”)
这是错误
"Loading name.repl..."
"Begin Tx 0: Load modules"
"Setting transaction data"
"Namespace defined: free"
"Loading root/fungible-v2.pact..."
"Loaded interface fungible-v2"
"Loading root/fungible-xchain-v1.pact..."
"Loaded interface fungible-xchain-v1"
"Loading root/coin-v5.pact..."
"Loaded module coin, hash b05fAfvjpnvnl_ssUgyTNkOIAN398ecTuTsUlW_RKyg"
"TableCreated"
"TableCreated"
"Loading name.pact..."
"Namespace set to free"
"Keyset defined"
Warning: using deprecated native overload for *: decimal/integer operator overload is deprecated
"Loaded module free.testingdomain, hash -Y3ux3ibsIwB8keMSmX67JYayvYsgsOlxdswa-OZwhY"
"Commit Tx 0: Load modules"
"Begin Tx 1: Create KDA accounts"
root/coin-v5.pact:516:12: Single-key account protocol violation
at root/coin-v5.pact:516:12: (enforce false "Single-key account protocol violation")
at root/coin-v5.pact:515:10: (if (native `=` Compare alike terms for equality, ret... (native `enforce` Fail transaction with MSG if pu... (native `enforce` Fail transaction with MSG if pu...)
at root/coin-v5.pact:513:8: (if (native `=` Compare alike terms for equality, ret... true (native `if` Test COND. If true, evaluate THEN. O...)
at root/coin-v5.pact:510:4: (if (native `validate-principal` Validate that PRINCI... true (let (r:<ap> (coin.check-reserved "k:36990b871267e...)
at root/coin-v5.pact:288:4: (enforce-reserved "k:36990b871267ec4532551e505260806d7f39378cebb5ea2... KeySet {keys: [domain-admin-gov-keyset],pred: keys...)
at name.repl:44:0: (create-account "k:36990b871267ec4532551e505260806d7f39378cebb5ea2... KeySet {keys: [domain-admin-gov-keyset],pred: keys...)
我已经为此苦苦挣扎了一段时间,我们将不胜感激。 谢谢。