Build on MultiversX
Building the Contract
We’re ready to see if the pieces fit together. Let’s build the contract:
sc-meta all build
This will generate the .wasm and .abi.json files in the output folder — our contract’s DNA!
Setting Funding Targets
Let’s make it interesting! Here, we’re setting a funding goal that our campaign will aim to reach. Add this to src/crowdfunding.rs:
#!\[no_std\]
multiversx_sc::imports!();
#\[multiversx_sc::contract\]
pub trait Crowdfunding {
#\[storage_mapper("target")\]
fn target(&self) -> SingleValueMapper<BigUint>;
#\[init\]
fn init(&self, target: BigUint) {
[self.target](http://self.target)().set(&target);
}
}
init(): Sets the target funding goal and deadline.
Now, let’s test that initial setup! This will check if the contract correctly sets up the target. Inside the Crowdfunding folder, create a file named crowdfunding-init.scen.json:
Let’s define a scenario:
{
"name": "crowdfunding deployment test",
"steps": \[
{
"step": "setState",
"accounts": {
"address:my_address": {
"nonce": "0",
"balance": "1,000,000"
}
},
"newAddresses": \[
{
"creatorAddress": "address:my_address",
"creatorNonce": "0",
"newAddress": "sc:crowdfunding"
}
\]
},
{
"step": "scDeploy",
"txId": "deploy",
"tx": {
"from": "address:my_address",
"contractCode": "file:../output/crowdfunding.wasm",
"arguments": \["500,000,000,000"\],
"gasLimit": "5,000,000",
"gasPrice": "0"
},
"expect": {
"out": \[\],
"status": "0",
"gas": "\*",
"refund": "\*"
}
},
{
"step": "checkState",
"accounts": {
"address:my_address": {
"nonce": "1",
"balance": "1,000,000",
"storage": {}
},
"sc:crowdfunding": {
"nonce": "0",
"balance": "0",
"storage": {
"str:target": "500,000,000,000"
},
"code": "file:../output/crowdfunding.wasm"
}
}
}
\]
}
Save the file. Do you want to try it out first? Go ahead and issue this command on your terminal:
cargo test
Implementing Core Logic
The first thing we need to do is to configure the desired target amount and the deadline. The deadline will be expressed as the block timestamp after which the contract can no longer be funded. We will be adding 2 more storage fields and arguments to the constructor:
#\[view(getTarget)\]
#\[storage_mapper("target")\]
fn target(&self) -> SingleValueMapper<BigUint>;
#\[view(getDeadline)\]
#\[storage_mapper("deadline")\]
fn deadline(&self) -> SingleValueMapper<u64>;
#\[view(getDeposit)\]
#\[storage_mapper("deposit")\]
fn deposit(&self, donor: &ManagedAddress) -> SingleValueMapper<BigUint>;
#\[init\]
fn init(&self, target: BigUint, deadline: u64) {
[self.target](http://self.target)().set(&target);
self.deadline().set(&deadline);
}
Comments
You need to enroll in the course to be able to comment!