- Preparation
- 1. Install KYC Contract
- 2. Install CaskNFT Contract
- 3. Mint a CaskNFT to bid
- Full Code Example
- 4. Install Auction Contract
- 5. Bid on the Auction
- 6. Cancel a bid
- 7. Auction Cancellation
- 8. Finalize the auction
Preparation
The Auction Contract requires two additional contracts to function:
-
An NFT contract with:
-
a
"transfer"
endpoint that has the following arguments:-
"sender"
-
"recipient"
-
"token_ids"
-
-
a
"token_commission"
endpoint with the following arguments:-
"token_id"
-
"property"
-
-
Currently only CaskNFT contract meets this requirement.
-
A KYC contract with:
-
"is_kyc_proved"
endpoint that has the arguments:-
"account"
-
"index"
-
-
1. Install KYC Contract
The civic contract can be cloned via the Casper Labs public repository.
After cloning the civic-contract and building the wasm file, to install the contract with the Casper JavaScript SDK:
Import Statements
The script begins with several import statements that import various functions and objects from the casper-js-sdk
module, as well as custom modules constants
and utils
.
import {
CasperClient,
DeployUtil,
RuntimeArgs,
CLString,
CLMap,
CLAccountHash,
CLPublicKey,
CLKey,
} from "casper-js-sdk";
import * as constants from "./constants";
import * as utils from "./utils";
-
CasperClient
: A class that provides a convenient interface to interact with a Casper blockchain node. -
DeployUtil
: A module that contains various utility functions for creating and signing deploys. -
RuntimeArgs
: A class for constructing runtime argument maps. -
CLString
: A class for representing a string value in CL (CasperLabs) format. -
CLMap
: A class for representing a map in CL format. -
CLAccountHash
: A class for representing an account hash in CL format. -
CLPublicKey
: A class for representing a public key in CL format. -
CLKey
: A class for representing a key in CL format. -
constants
: A module that contains various constants used in the script. -
utils
: A module that contains various utility functions used in the script.
Constants
Next, the script declares several constants that are used throughout the script.
const PATH_TO_CONTRACT =
"/path/to/civic-contract/target/wasm32-unknown-unknown/release/civic-token.wasm";
const TOKEN_NAME = new CLString("TREE Token");
const TOKEN_SYMBOL = new CLString("TREE");
const myKey = new CLString("hello");
const myVal = new CLString("world");
const TOKEN_META = new CLMap([[myKey, myVal]]);
const TOKEN_contract_name = new CLString("KYC");
const hexString1 =
"01a37aa7597857d4cd40a657109c3df021682bbe4c1c31c17da1df0835599b3a62";
const myHash1 = new CLAccountHash(
CLPublicKey.fromHex(hexString1).toAccountHash()
);
const TOKEN_ADMIN = new CLKey(myHash1);
-
PATH_TO_CONTRACT
: The file path of the contract that will be installed. -
TOKEN_NAME
: ACLString
object representing the name of the token. -
TOKEN_SYMBOL
: ACLString
object representing the symbol of the token. -
myKey
: ACLString
object representing a key used in theTOKEN_META
map. -
myVal
: ACLString
object representing a value used in theTOKEN_META
map. -
TOKEN_META
: ACLMap
object representing a map of metadata for the token. -
TOKEN_contract_name
: ACLString
object representing the name of the contract. -
hexString1
: A hex string representing an account hash. -
myHash1
: ACLAccountHash
object representing the account hash derived fromhexString1
. -
TOKEN_ADMIN
: ACLKey
object representing the key of the token administrator.
After the constants are defined, we come to the main
function, which is the entry point for the script:
const main = async () => {
// Step 1: Set casper node client.
const client = new CasperClient(constants.DEPLOY_NODE_ADDRESS);
// Step 2: Set contract operator key pair.
const keyPairOfContract = utils.getKeyPairOfContract(
constants.PATH_TO_KYC_KEYS
);
// Step 3: Set contract installation deploy (unsigned).
let deploy = DeployUtil.makeDeploy(
new DeployUtil.DeployParams(
keyPairOfContract.publicKey,
constants.DEPLOY_CHAIN_NAME,
constants.DEPLOY_GAS_PRICE,
constants.DEPLOY_TTL_MS
),
DeployUtil.ExecutableDeployItem.newModuleBytes(
utils.getBinary(PATH_TO_CONTRACT),
RuntimeArgs.fromMap({
name: TOKEN_NAME,
symbol: TOKEN_SYMBOL,
meta: TOKEN_META,
admin: TOKEN_ADMIN,
contract_name: TOKEN_contract_name,
})
),
DeployUtil.standardPayment(300000000000)
);
// Step 4: Sign deploy.
deploy = client.signDeploy(deploy, keyPairOfContract);
// Step 5: Dispatch deploy to node.
const deployHash = await client.putDeploy(deploy);
// Step 6: Render deploy details.
logDetails(deployHash);
};
/**
* Emits to stdout deploy details.
* @param {String} deployHash - Identifer of dispatched deploy.
*/
const logDetails = (deployHash) => {
console.log(`
---------------------------------------------------------------------
installed contract -> CASK
... account = ${constants.PATH_TO_SOURCE_KEYS}
... deploy chain = ${constants.DEPLOY_CHAIN_NAME}
... deploy dispatch node = ${constants.DEPLOY_NODE_ADDRESS}
... deploy gas price = ${constants.DEPLOY_GAS_PRICE}
contract installation details:
... path = ${PATH_TO_CONTRACT}
... deploy hash = ${deployHash}
---------------------------------------------------------------------
`);
};
main();
2. Install CaskNFT Contract
The civic CaskNFT can be cloned via the Casper Labs public CaskNFT repository.
After cloning the civic-contract and building the wasm file, to install the contract with the Casper JavaScript SDK:
Token Parameters
// Token parameters.
const TOKEN_NAME = new CLString("Cask Token");
const TOKEN_SYMBOL = new CLString("CASK");
const myKey = new CLString("hello");
const myVal = new CLString("world");
const TOKEN_META = new CLMap([[myKey, myVal]]);
const TOKEN_contract_name = new CLString("CVCV");
-
TOKEN_NAME
: ACLString
object representing the name of the token. -
TOKEN_SYMBOL
: ACLString
object representing the ticker symbol of the token. -
myKey
: ACLString
object representing a key used in theTOKEN_META
map. -
myVal
: ACLString
object representing a value used in theTOKEN_META
map. -
TOKEN_META
: ACLMap
object representing a map of metadata for the token. -
TOKEN_contract_name
: ACLString
object representing the name of the contract.
Setting the Account Hash
//**************************** account-hash start*******************************/
// nctl-view-user-account user=1
const hexString1 =
"01cec85e263f49e660ae853b30849a0205e763ea35f644c69d4b05f02a4606afaf";
const myHash1 = new CLAccountHash(
CLPublicKey.fromHex(hexString1).toAccountHash()
);
const TOKEN_ADMIN = new CLKey(myHash1);
//**************************** account-hash end*******************************/
This section sets the account hash that will be used as the admin of the smart contract. An account hash is a cryptographic hash of a public key that is used to identify an account on the blockchain. In this example, the account hash is hard-coded as a hexadecimal string in hexString1. The CLPublicKey.fromHex(hexString1).toAccountHash() call converts this string into an account hash, which is then used to create a CLKey object that will be used as the admin of the smart contract.
Setting the KYC Package Hash
//**************************** kyc_package start*******************************/
const hexString2 =
"55eac7c6eb754dbbd0b3b989b23528c49f6819f4f2519d9e00fa8566ef557d88";
const hex2 = Uint8Array.from(Buffer.from(hexString2, "hex"));
const TOKEN_kyc_package_hash = new CLKey(new CLByteArray(hex2));
//**************************** kyc_package end*******************************/
The code also sets up a KYC package hash using another hex string. This hash is used to specify the KYC package that will be associated with the deployed smart contract.
Main Function
The main function is the primary entry point for the script. This function performs the following tasks:
-
Sets up the Casper client.
-
Sets up the key pair for the contract operator.
-
Generates a deploy to install the contract.
-
Signs the deploy.
-
Dispatches the deploy to the Casper blockchain.
-
Logs deploy details to the console.
const main = async () => {
// Step 1: Set casper node client.
const client = new CasperClient(constants.DEPLOY_NODE_ADDRESS);
// Step 2: Set contract operator key pair.
const keyPairOfContract = utils.getKeyPairOfContract(
constants.PATH_TO_SOURCE_KEYS
);
// Step 3: Set contract installation deploy (unsigned).
let deploy = DeployUtil.makeDeploy(
new DeployUtil.DeployParams(
keyPairOfContract.publicKey,
constants.DEPLOY_CHAIN_NAME,
constants.DEPLOY_GAS_PRICE,
constants.DEPLOY_TTL_MS
),
DeployUtil.ExecutableDeployItem.newModuleBytes(
utils.getBinary(PATH_TO_CONTRACT),
RuntimeArgs.fromMap({
name: TOKEN_NAME,
symbol: TOKEN_SYMBOL,
meta: TOKEN_META,
admin: TOKEN_ADMIN,
kyc_package_hash: TOKEN_kyc_package_hash,
contract
3. Mint a CaskNFT to bid
Setting the Casper Node Client
const client = new CasperClient(constants.DEPLOY_NODE_ADDRESS);
The first step in our main function is to create a new instance of the CasperClient class, which is provided by the Casper SDK. This class provides a way to interact with the Casper blockchain via RPC calls.
Here, we're passing in a constant value constants.DEPLOY_NODE_ADDRESS to set the Casper node client's endpoint.
Setting the Contract Operator Key Pair
const keyPairofContract = utils.getKeyPairOfContract(
constants.PATH_TO_SOURCE_KEYS
);
Next, we need to set the key pair of the contract operator. The utils.getKeyPairOfContract function returns a key pair object that includes both a public and private key. We're passing in the path to the source keys file as a parameter, which is stored in the constants.js file.
Getting the Contract Hash
const constracthash_str =
"hash-adc92723c7e7cd599d84352d1c13f4240686532ab88c1cd6365973c0ddbcbb1d";
const contractHashAsByteArray = [
...Buffer.from(constracthash_str.slice(5), "hex"),
];
Here, we're getting the contract hash. We're storing it as a string in constracthash_str and converting it to a byte array using the Buffer.from method. We're then storing the result in contractHashAsByteArray.
Setting the Recipient
const hexString =
"01cec85e263f49e660ae853b30849a0205e763ea35f644c69d4b05f02a4606afaf";
const hash = CLPublicKey.fromHex(hexString).toAccountHash();
const accounthash = new CLAccountHash(hash);
const recipient = new CLKey(accounthash);
Next, we need to set the recipient of the tokens we want to transfer. Here, we're creating a new CLPublicKey object from a hex string, then converting it to an AccountHash.
Set Token Information
This includes the token ID, metadata, and commissions. This is done using the following code:
const a = new CLString("orange");
const myList = new CLList([a]);
const token_ids = new CLOption(Some(myList));
const token1_myKey1 = new CLString("ice_account");
const token1_myVal1 = new CLString(
"account-hash-9f3e78530d55f5ec09d6b331127744d9abe6142276bf0728b69348d55d053e21"
);
const token1_myKey2 = new CLString("ice_rate");
const token1_myVal2 = new CLString("2");
const token1_commission = new CLMap([
[token1_myKey1, token1_myVal1],
[token1_myKey2, token1_myVal2],
]);
const token_metas = new CLList([token1_commission]);
const token_commissions = new CLList([token1_commission]);
This code sets the token ID to the string "orange" and creates a list of tokens with a single element. It then creates a commission map and populates it with two key-value pairs, with the keys "ice_account" and "ice_rate" respectively.
Invoking the transfer endpoint
//Step 5: Invoke contract transfer endpoint.
//Step 5.1 Set deploy
let deploy = DeployUtil.makeDeploy(
new DeployUtil.DeployParams(
keyPairofContract.publicKey,
constants.DEPLOY_CHAIN_NAME,
constants.DEPLOY_GAS_PRICE,
constants.DEPLOY_TTL_MS
),
DeployUtil.ExecutableDeployItem.newStoredContractByHash(
contractHashAsByteArray,
"mint",
RuntimeArgs.fromMap({
recipient: recipient,
token_ids: token_ids,
token_metas: token_metas,
token_commissions: token_commissions,
})
),
DeployUtil.standardPayment(
constants.DEPLOY_GAS_PAYMENT_FOR_SESSION_TRANSFER
)
);
This code block creates a new deploy object using the makeDeploy() method provided by the CasperJS SDK. The makeDeploy() method requires three parameters:
-
DeployParams
: an object that contains the public key of the contract operator, the name of the chain the deploy will be executed on, the gas price for the deploy, and the time to live (TTL) for the deploy. -
ExecutableDeployItem
: an object that contains the contract hash, the name of the contract method to be invoked, and the arguments for the method. -
Payment
: an object that specifies the amount of gas to be paid for the execution of the deploy.
In this code block, the DeployParams
object is constructed using the publicKey
property of the keyPairofContract
object, the DEPLOY_CHAIN_NAME
, DEPLOY_GAS_PRICE
, and DEPLOY_TTL_MS
constants.
The ExecutableDeployItem
object is created using the newStoredContractByHash()
method, which takes the contractHashAsByteArray
variable, the string "mint"
, and a RuntimeArgs
object as parameters. The RuntimeArgs
object is constructed using a JavaScript object with four properties: recipient
, token_ids
, token_metas
, and token_commissions
. These properties are populated with the recipient
, token_ids
, token_metas
, and token_commissions
variables that were created earlier in the code.
The Payment
object is created using the standardPayment()
method, which takes the DEPLOY_GAS_PAYMENT_FOR_SESSION_TRANSFER
constant as a parameter. This constant specifies the amount of gas to be paid for the execution of the deploy.
//Step 5.2 Sign deploy.
deploy = client.signDeploy(deploy, keyPairofContract);
This code block signs the deploy object with the keyPairofContract object using the signDeploy() method provided by the CasperJS SDK. The signed deploy is then assigned back to the deploy variable.
//Step 5.3 Dispatch deploy to node.
let deployHash = await client.putDeploy(deploy);
console.log(`deploy hash = ${deployHash}`);
};
main();
This code block dispatches the signed deploy object to the Casper node using the putDeploy() method provided by the CasperJS SDK. The putDeploy() method returns a promise that resolves with the deploy hash if the deploy is successfully dispatched. The deploy hash is assigned to the deployHash variable and logged to the console. The main() function is then called to run the script.
Full Code Example
Below is a the full body of code for this example, also viewable here.
import {
DeployUtil,
CasperClient,
RuntimeArgs,
CLMap,
CLList,
CLKey,
CLAccountHash,
CLString,
CLPublicKey,
CLOption,
} from "casper-js-sdk";
import * as utils from "./utils";
import { Some, None } from "ts-results";
import * as constants from "./constants";
const main = async () => {
//Step 1: Set casper node client
const client = new CasperClient(constants.DEPLOY_NODE_ADDRESS);
//Step 2: Set contract operator key pair
const keyPairofContract = utils.getKeyPairOfContract(
constants.PATH_TO_SOURCE_KEYS
);
//Step4: get contract hash
const constracthash_str =
"hash-adc92723c7e7cd599d84352d1c13f4240686532ab88c1cd6365973c0ddbcbb1d";
const contractHashAsByteArray = [
...Buffer.from(constracthash_str.slice(5), "hex"),
];
// recipient
const hexString =
"01cec85e263f49e660ae853b30849a0205e763ea35f644c69d4b05f02a4606afaf";
const hash = CLPublicKey.fromHex(hexString).toAccountHash();
const accounthash = new CLAccountHash(hash);
const recipient = new CLKey(accounthash);
const a = new CLString("orange");
const myList = new CLList([a]);
const token_ids = new CLOption(Some(myList));
// nctl-view-user-account user=6
const token1_myKey1 = new CLString("ice_account");
const token1_myVal1 = new CLString(
"account-hash-9f3e78530d55f5ec09d6b331127744d9abe6142276bf0728b69348d55d053e21"
);
const token1_myKey2 = new CLString("ice_rate");
const token1_myVal2 = new CLString("2");
const token1_commission = new CLMap([
[token1_myKey1, token1_myVal1],
[token1_myKey2, token1_myVal2],
]);
const token_metas = new CLList([token1_commission]);
const token_commissions = new CLList([token1_commission]);
//Step 5: Invoke contract transfer endpoint.
//Step 5.1 Set deploy
let deploy = DeployUtil.makeDeploy(
new DeployUtil.DeployParams(
keyPairofContract.publicKey,
constants.DEPLOY_CHAIN_NAME,
constants.DEPLOY_GAS_PRICE,
constants.DEPLOY_TTL_MS
),
DeployUtil.ExecutableDeployItem.newStoredContractByHash(
contractHashAsByteArray,
"mint",
RuntimeArgs.fromMap({
recipient: recipient,
token_ids: token_ids,
token_metas: token_metas,
token_commissions: token_commissions,
})
),
DeployUtil.standardPayment(
constants.DEPLOY_GAS_PAYMENT_FOR_SESSION_TRANSFER
)
);
//Step 5.2 Sign deploy.
deploy = client.signDeploy(deploy, keyPairofContract);
//Step 5.3 Dispatch deploy to node.
let deployHash = await client.putDeploy(deploy);
console.log(`deploy hash = ${deployHash}`);
};
main();
4. Install Auction Contract
The private auction contract can be cloned via the Casper Labs (public) Private Auction repository.
After cloning the private auction contract and building the wasm file, to install the contract with the Casper casper-client CLI tool:
casper-client put-deploy --chain-name casper-net-1 \
--node-address http://localhost:11101/rpc \
--session-path /path/to/casper-private-auction/target/wasm32-unknown-unknown/release/casper-private-auction-installer.wasm \
--session-arg "name:string='myname'" \
--session-arg "token_contract_hash:key='hash-0b879dbf76f95bb0afa0a9dd497f81aa7faabd7b40abf40883cf23d3b35ac79a'" \
--session-arg "token_id:string='orange'" \
--session-arg "has_enhanced_nft:bool='false'" \
--session-arg "beneficiary_account:key='account-hash-65325cfe49c14ff3160d84b76a4bd786cb09e40b10ffbe37c5a9782cfe1e521f'" \
--session-arg "kyc_package_hash:key='hash-55eac7c6eb754dbbd0b3b989b23528c49f6819f4f2519d9e00fa8566ef557d88'" \
--session-arg "format:string=ENGLISH'" \
--session-arg "starting_price:opt_u512=null" \
--session-arg "reserve_price:u512='8'" \
--session-arg "bidder_count_cap:opt_u64=123'" \
--session-arg "auction_timer_extension:opt_u64=123'" \
--session-arg "minimum_bid_step:opt_u512=123'" \
--session-arg "marketplace_account:account_hash='account-hash-abb644f6bb15a79ed03e2755a623f1f2163c9c6a130870c42118376357b57b81'" \
--session-arg "marketplace_commission:u32=123'" \
--session-arg "start_time:u64=1680492634000'" \
--session-arg "cancellation_time:u64=1680493234000'" \
--session-arg "end_time:u64=1680494374000'" \
--payment-amount 200000000000 \
--secret-key /path/to/secret_key.pem
-
--chain-name casper-net-1
- This flag specifies the name of the network chain you want to deploy the contract on. In this case, we are deploying it on thecasper-net-1
network. -
--node-address http://localhost:11101/rpc
- This flag specifies the URL of the node you want to send the deploy to. In this case, we are sending it to a node running onlocalhost
on port11101
. -
--session-path /home/jh/caspereco/casper-private-auction/target/wasm32-unknown-unknown/release/casper-private-auction-installer.wasm
- This flag specifies the path to the compiled contract file you want to deploy. In this case, we are deploying thecasper-private-auction-installer.wasm
file located in the specified directory. -
--session-arg
- This flag is used to pass arguments to the contract during deployment. We're passing several arguments, including:-
"beneficiary_account"
: Key-account type of the account you wish to receive any motes that weren't distributed after commissions were paid -
"token_contract_hash"
: Key-hash type of the contract package hash of the NFT contract -
"kyc_package_hash"
: Key-hash type of the contract package hash of the KYC contract -
"format"
: String data to tell the contract to run an English or a Dutch auction (onlyENGLISH
orDUTCH
are valid data, capitalization is necessary) -
"starting_price"
: Option<U512> type. Dutch auction starting price. English auction doesn't use this, so it requires this to benull
or will fail to deploy. -
"reserve_price"
: U512 type of reserve price, aka the smallest permitted selling price. -
"token_id"
: String ID of the NFT token put up for auction. -
"start_time"
: u64 UNIX timestamp of the auction's starting time. -
"cancellation_time"
: u64 UNIX timestamp of the latest time bids on the auction can be cancelled. -
"end_time"
: u64 UNIX timestamp of the time the auction will end. -
"name"
: String name of this particular account. -
"bidder_count_cap"
: Option<u64> type, an argument to limit the number of distinct bidders. -
"auction_timer_extension"
: Option<u64> type, on successful bids extends the end and cancellation times of the auction. -
"minimum_bid_step"
: Option<U512> type, if a value is given, the next successful bid needs to be at leastminimum_bid_step
higher than the previous. -
"marketplace_account"
: AccountHash type, account hash of the marketplace. -
"marketplace_commission"
: u32 type, commission of the marketplace.
-
-
--payment-amount 200000000000
- This flag specifies the amount of motes (the smallest unit of Casper) to attach to the deploy as payment. In this case, we're attaching 200000000000 motes (or 200 Casper) as payment. -
--secret-key /path/to/secret_key.pem
- This flag specifies the path to the secret key file needed to sign the deploy. This file contains the private key for the account you want to use to deploy the contract.
5. Bid on the Auction
Now it’s time to bid on the auction. Only accounts that have passed KYC are able to bid. To bid on the auction, you first call the mint
entrypoint of the KYC contract from each account to bid.
Set Casper node client
We start the bid script by again first setting up the Casper node client using the CasperClient
constructor function. The address of the node is passed as an argument to the function.
Set contract operator key pair
The next step is to set the key pair of the account that is authorized to interact with the smart contract. This key pair is used to sign the deploy later on.
const keyPairofContract = utils.getKeyPairOfContract(
constants.PATH_TO_KYC_KEYS
);
Get contract hash
This hash is used to identify the smart contract on the blockchain.
const constracthash_str =
"hash-a1fb32f330214b638e926e3c6fc8a2b1a9d94e20f3eae5a15685409778a9b90e";
const contractHashAsByteArray = [
...Buffer.from(constracthash_str.slice(5), "hex"),
];
Set recipient address
The address is converted from a hexadecimal string to an AccountHash using the CLPublicKey.fromHex() function. The CLKey constructor is then used to create a new instance of a key using the AccountHash.
const hexString =
"010ce51039a7bf51e5b8d5afe40b7a221c9c37e1b1a8567c587d455b6a6394ec78";
const hash = CLPublicKey.fromHex(hexString).toAccountHash();
const accounthash = new CLAccountHash(hash);
const recipient = new CLKey(accounthash);
Set NFT token information
The token_id is set to "apple" using the CLString constructor. This value is then wrapped in an optional CLOption using the Some() function. A CLMap instance is then created using a key and value pair.
const a = new CLString("apple");
const token_id = new CLOption(Some(a));
const myKey = new CLString("status");
const myVal = new CLString("active");
const token_meta = new CLMap([[myKey, myVal]]);
Create and send deploy
The makeDeploy() function is used to create a new deploy. The DeployParams instance contains information such as the public key of the account that is signing the deploy, the chain name, gas price, and time to live. The ExecutableDeployItem is then created using the contract hash, "mint" entrypoint, and RuntimeArgs instance containing the recipient, token ID, and token metadata. The standardPayment() function is used to set the payment for the deploy.
//Step 5.1 Set deploy
let deploy = DeployUtil.makeDeploy(
new DeployUtil.DeployParams(
keyPairofContract.publicKey,
constants.DEPLOY_CHAIN_NAME,
constants.DEPLOY_GAS_PRICE,
constants.DEPLOY_TTL_MS
),
DeployUtil.ExecutableDeployItem.newStoredContractByHash(
contractHashAsByteArray,
"mint",
RuntimeArgs.fromMap({
recipient: recipient,
token_id: token_id,
token_meta: token_meta,
})
),
DeployUtil.standardPayment(
constants.DEPLOY_GAS_PAYMENT_FOR_SESSION_TRANSFER
)
);
//Step 5.2 Sign deploy.
deploy = client.signDeploy(deploy, keyPairofContract);
//Step 5.3 Send deploy to node.
let deployHash = await client.putDeploy(deploy);
console.log(`deploy hash = ${deployHash}`);
};
main();
The full body of code from this part of the guide:
import {
DeployUtil,
CasperClient,
RuntimeArgs,
CLMap,
CLKey,
CLAccountHash,
CLString,
CLPublicKey,
CLOption,
} from "casper-js-sdk";
import * as utils from "./utils";
import { Some, None } from "ts-results";
import * as constants from "./constants";
const main = async () => {
//Step 1: Set casper node client
const client = new CasperClient(constants.DEPLOY_NODE_ADDRESS);
//Step 2: Set contract operator key pair
const keyPairofContract = utils.getKeyPairOfContract(
constants.PATH_TO_KYC_KEYS
);
//Step4: get contract hash
const constracthash_str =
"hash-a1fb32f330214b638e926e3c6fc8a2b1a9d94e20f3eae5a15685409778a9b90e";
const contractHashAsByteArray = [
...Buffer.from(constracthash_str.slice(5), "hex"),
];
// recipient
const hexString =
"010ce51039a7bf51e5b8d5afe40b7a221c9c37e1b1a8567c587d455b6a6394ec78";
const hash = CLPublicKey.fromHex(hexString).toAccountHash();
const accounthash = new CLAccountHash(hash);
const recipient = new CLKey(accounthash);
const a = new CLString("apple");
const token_id = new CLOption(Some(a));
const myKey = new CLString("status");
const myVal = new CLString("active");
const token_meta = new CLMap([[myKey, myVal]]);
//Step 5: Invoke contract transfer endpoint.
//Step 5.1 Set deploy
let deploy = DeployUtil.makeDeploy(
new DeployUtil.DeployParams(
keyPairofContract.publicKey,
constants.DEPLOY_CHAIN_NAME,
constants.DEPLOY_GAS_PRICE,
constants.DEPLOY_TTL_MS
),
DeployUtil.ExecutableDeployItem.newStoredContractByHash(
contractHashAsByteArray,
"mint",
RuntimeArgs.fromMap({
recipient: recipient,
token_id: token_id,
token_meta: token_meta,
})
),
DeployUtil.standardPayment(
constants.DEPLOY_GAS_PAYMENT_FOR_SESSION_TRANSFER
)
);
//Step 5.2 Sign deploy.
deploy = client.signDeploy(deploy, keyPairofContract);
//Step 5.3 Dispatch deploy to node.
let deployHash = await client.putDeploy(deploy);
console.log(`deploy hash = ${deployHash}`);
};
main();
Bid on auction with KYC passed account
With an account that has “passed” the KYC requirements, you can now bid on an auction. Using user-1 on an NCTL network, you would bid on an auction using something similar to:
casper-client put-deploy --chain-name casper-net-1 \
--node-address http://localhost:11101/rpc \
--session-path /path/to/casper-private-auction/target/wasm32-unknown-unknown/release/bid-purse.wasm \
--session-arg "amount:u512='1000'" \
--session-arg "auction_contract:account_hash='account-hash-59ebecce6cd7e80e634730bc6290c694339d553a4c34dcbb5a3507090dd3fd2d'" \
--session-arg "purse_name:string='mypurse'" \
--payment-amount 200000000000 \
--secret-key /path/to/casper-node/utils/nctl/assets/net-1/users/user-1/secret_key.pem
Place a new competing/winning bid
Using a second KYC-passed account, the new bid must be higher than the previous bid.
casper-client put-deploy --chain-name casper-net-1 \
--node-address http://localhost:11101/rpc \
--session-path /path/to/casper-private-auction/target/wasm32-unknown-unknown/release/bid-purse.wasm \
--session-arg "amount:u512='1124'" \
--session-arg "auction_contract:account_hash='account-hash-59ebecce6cd7e80e634730bc6290c694339d553a4c34dcbb5a3507090dd3fd2d'" \
--session-arg "purse_name:string='mypurse'" \
--payment-amount 200000000000 \
--secret-key /path/to/casper-node/utils/nctl/assets/net-1/users/user-2/secret_key.pem
After you place a bid,you can check the bid amount and how many accounts have bid on the auction.
Retrieve bid
Bids can be retrieved using the casper-client get-dictionary-item command:
stateroothash=$(casper-client get-state-root-hash -n http://localhost:11101 | jq .result.state_root_hash | tr -d '"'); \
casper-client get-dictionary-item -n http://localhost:11101 \
--dictionary-item-key dd19516a95f63950a0de97fcfb7a825d835b8461acec289c62e29ab575e98334 \
--state-root-hash $stateroothash \
--seed-uref uref-138aa997c12d268d32fd45596fd4cbac4106530f006912b52a204ed3cc8e9f73-007
-
seed-uref is the contract’s named_key bids_key.
-
dictionary-item-key is the account hash, stripping the preceeding account-hash-
Get the number of accounts that have bid on the auction
Using the contract’s NamedKey bids_index as the --seed-uref argument, you can get the len of the dictionary, for a count of all bids on the auction.
stateroothash=$(casper-client get-state-root-hash -n http://localhost:11101 | jq .result.state_root_hash | tr -d '"'); \
casper-client get-dictionary-item -n http://localhost:11101 \
--dictionary-item-key len \
--state-root-hash $stateroothash \
--seed-uref uref-f6b47e4d883c71f28b6f108c3cd05761d583ec4bb48a6e2a78405940cf1b06fd-007
6. Cancel a bid
If a bidder is still within the timeframe set with the session-argument cancellation_time from when the auction contract was installed, they can cancel their bid:
casper-client put-deploy --chain-name casper-net-1 \
--node-address http://localhost:11101/rpc \
--session-hash hash-6cb16ca5b5c204e72f8c3ca2886d4a5f8113be5fd50c98c7586fcc59395ff720 \
--session-entry-point cancel_bid \
--payment-amount 200000000000 \
--secret-key /path/to/casper-node/utils/nctl/assets/net-1/users/user-2/secret_key.pem
7. Auction Cancellation
If there are no bids to the auction, the auction creator can cancel the auction entirely:
casper-client put-deploy --chain-name casper-net-1 \
--node-address http://localhost:11101/rpc \
--session-hash hash-a114e14b72eb9e3df6aa02a9d64677ed23dd78dc501a16ceee171142c7a5da51 \
--session-entry-point cancel_auction \
--payment-amount 200000000000 \
--secret-key /path/to/casper-node/utils/nctl/assets/net-1/users/user-1/secret_key.pem
8. Finalize the auction
Upon calling the finalize entrypoint, the winning bid gets the NFT and the following accounts get their share of the winning bid:
-
marketplace_account
-
commission_accounts
-
beneficiary_account
-
failed bids get their refunds.
When the auction ends:
If there were no winning bids or an error occurred:
-
every bid is returned to the respective bidder
-
The NFT token is returned to the original owner.
In the result of a winning bid and no errors:
-
The winning bidder receives the NFT.
-
Non-winning bids are refunded.
-
The winning bid is divided and disbursed to the accounts listed in the NFT Token commision metadata. All remaining motes of CSPR are sent to the beneficiary account provided when deploying the contract.
casper-client put-deploy --chain-name casper-net-1 \
--node-address http://localhost:11101/rpc \
--session-hash hash-59ebecce6cd7e80e634730bc6290c694339d553a4c34dcbb5a3507090dd3fd2d \
--session-entry-point finalize \
--payment-amount 200000000000 \
--secret-key /path/to/casper-node/utils/nctl/assets/net-1/users/user-1/secret_key.pem
Comments
0 comments
Please sign in to leave a comment.