eigerco / nebula

A soroban contract library
https://nebula.eiger.co
Apache License 2.0
7 stars 2 forks source link

Choose/elaborate a configurable smart contract to add to Nebula's UI #5

Closed eloylp closed 1 year ago

eloylp commented 1 year ago

Context

A part of Nebula is going to be an UI that helps developers building smart contracts in a configurable way.

Goals

eloylp commented 1 year ago

Alright ! we have one candidate here ready for review : https://github.com/eigerco/nebula/pull/12

Its about a simple voting example. I think it could be easily configurable by the wizard. Its still a draft though, waiting for feedback :)

Others are under investigation right now, like the raffle and fundme contracts.

Adding @geofmureithi and @mariopil to the :loop: !

eloylp commented 1 year ago

We have the raffle example https://github.com/eigerco/nebula/pull/13 ready for review.

eloylp commented 1 year ago

Alright ! we are unit testing the contracts, but maybe its a good moment to check the soroban tools for deploying them. Looks like we have plenty of options !

I think i am going to test both in review contracts and write here my findings.

cc: @geofmureithi

eloylp commented 1 year ago

Alright ! after some difficulties with the tooling and the Futurenet network downtime, we can start publishing some results here.

Before that lets just take into account that:

eloylp commented 1 year ago

Raffle contract example Futurenet test results

Alright, lets test the lottery contract :popcorn: ! We need to do some preparations in order to achieve this. Lets create our admin contract and players ! For doing that, we need to go to the laboratory. We have created and fund (with friendbot faucet helper) the following addresses:

name balance pub key priv key
Admin 10000 GAH6O4LPMME6INTWXFS3IVZBGDSCN7KCSIAENUNDVQEJKT2D5ILLNYYR SCXBOAMHMCLODJ6IAA55RPOHJWHQMXU6YUI24JUH6SEL7XHGDXOKK3RM
Player1 10000 GDASG2GN2FLMJEVPW423LW6UVVLZXNGLU7H5QR5IHAJCE3VWKSOSRRC6 SDMBPBRM4TY33SB7PJ3X46I4OOEAIP4LU4CGLX7DCWBJZH6BLEMQJHSB
Player2 10000 GDO7GIFCWUJVN5P7EN6ONTOWYT2EOLDFUXDM75VYMWKX63EGLCXZG6HX SBNQKZMBOI4SUK4MGAYZ4RKP52DMJBDOU4UCZRHEI5WTRPBWLF2XNJX2
Player3 10000 GC5TAMTUAMBTNP6RZS5CPPC3ZVAQEYWV5DYWLQPV4U5LO56OOQXYG6DZ SDGU62DH5OT7DQU64GXARHDPWMTNL6VYGDPJYYO4DBV2VCI5TILUURAU

Now we need to build the contract by going to root of the contract folder contracts/lottery and execute:

$ soroban contract build

Then, optimise the wasm by:

$ cargo install soroban-cli --features opt
$ soroban contract optimize --wasm target/wasm32-unknown-unknown/release/lottery.wasm
Reading: target/wasm32-unknown-unknown/release/lottery.wasm (6476 bytes)
Writing to: target/wasm32-unknown-unknown/release/lottery.optimized.wasm...
Optimized: target/wasm32-unknown-unknown/release/lottery.optimized.wasm (5089 bytes)

That will give us the needed wasm file under target/wasm32-unknown-unknown/release/lottery.optimized.wasm we need to deploy:

$ soroban contract deploy \
--source SCXBOAMHMCLODJ6IAA55RPOHJWHQMXU6YUI24JUH6SEL7XHGDXOKK3RM \
--wasm target/wasm32-unknown-unknown/release/lottery.optimized.wasm \
--rpc-url https://rpc-futurenet.stellar.org:443 \
--network-passphrase 'Test SDF Future Network ; October 2022'

CAUKCX6RZPDM25L5YFTBUIZK5WDTTB4SHL2WB65EULRCRIP25PWNEXC3

As we are testing in Futurenet, the address token of native XLM can change when resets occurs. We need to query it and use it as --token param of the next command:

$ soroban lab token id --asset native --network futurenet
CB64D3G7SM2RTH6JSGG34DDTFTQ5CFDKVDZJZSODMCX4NJ2HV2KN7OHT

Now we need to initialise our raffle. Lets invoke the init function of the contract:

soroban contract invoke \
--id CAUKCX6RZPDM25L5YFTBUIZK5WDTTB4SHL2WB65EULRCRIP25PWNEXC3 \
--source SCXBOAMHMCLODJ6IAA55RPOHJWHQMXU6YUI24JUH6SEL7XHGDXOKK3RM \
--rpc-url https://rpc-futurenet.stellar.org:443 \
--network-passphrase 'Test SDF Future Network ; October 2022' \
-- \
init \
--admin GAH6O4LPMME6INTWXFS3IVZBGDSCN7KCSIAENUNDVQEJKT2D5ILLNYYR \
--token CB64D3G7SM2RTH6JSGG34DDTFTQ5CFDKVDZJZSODMCX4NJ2HV2KN7OHT \
--max_winners_count 1 \
--ticket_price 5001

Great ! we have our raffle initialised. Lets buy some tickets now for player1:

soroban contract invoke \
--id CAUKCX6RZPDM25L5YFTBUIZK5WDTTB4SHL2WB65EULRCRIP25PWNEXC3 \
--source SDMBPBRM4TY33SB7PJ3X46I4OOEAIP4LU4CGLX7DCWBJZH6BLEMQJHSB \
--rpc-url https://rpc-futurenet.stellar.org:443 \
--network-passphrase 'Test SDF Future Network ; October 2022' \
-- \
buy_ticket \
--by GDASG2GN2FLMJEVPW423LW6UVVLZXNGLU7H5QR5IHAJCE3VWKSOSRRC6

1

Notice we changed the --source param with the private key of player1 and also specified the --by parameter with the pub key of the same player. This operation should be repeated per each player. It returns 1 as the number of current participants. It should increment as we invoke that function more times.

Now its time to play the raffle ! Lets invoke it by:

soroban contract invoke \
--id CAUKCX6RZPDM25L5YFTBUIZK5WDTTB4SHL2WB65EULRCRIP25PWNEXC3 \
--source SCXBOAMHMCLODJ6IAA55RPOHJWHQMXU6YUI24JUH6SEL7XHGDXOKK3RM \
--rpc-url https://rpc-futurenet.stellar.org:443 \
--network-passphrase 'Test SDF Future Network ; October 2022' \
-- \
play_raffle \
--random_seed 1234

By checking the balances of our users, we can assert it worked well:

We can observe by the new balances that player 2 won the raffle. But lets confirm that by checking the contract events:

  1. Search transactions for admin in the laboratory. Get the latest one.
  2. Events are part of the transaction output, and are stored in the result_meta_xdr field. We can just click on it and the laboratory will redirect us to the decoded content.
  3. Search in that page for "events" and something like this will appear: image
  4. If we base64 decode the first topic of the event, we can confirm this indicates the winner of the raffle.
    ❯ echo "d2lubmVy" | base64 -d 
    winner

    The next topic GDO7GIFCWUJVN5P7EN6ONTOWYT2EOLDFUXDM75VYMWKX63EGLCXZG6HX is the public key/address of the winner, which matches the Player2 address.

With this steps, we just confirmed the raffle is properly working for the happy path in Futurenet.

Other notes

eloylp commented 1 year ago

Voting contract example Futurenet test results

Alright, lets test the voting contract :popcorn: ! We will use the same accounts from the raffle example.

name pub key priv key
Admin GAH6O4LPMME6INTWXFS3IVZBGDSCN7KCSIAENUNDVQEJKT2D5ILLNYYR SCXBOAMHMCLODJ6IAA55RPOHJWHQMXU6YUI24JUH6SEL7XHGDXOKK3RM
Voter1 GDASG2GN2FLMJEVPW423LW6UVVLZXNGLU7H5QR5IHAJCE3VWKSOSRRC6 SDMBPBRM4TY33SB7PJ3X46I4OOEAIP4LU4CGLX7DCWBJZH6BLEMQJHSB
Voter2 GDO7GIFCWUJVN5P7EN6ONTOWYT2EOLDFUXDM75VYMWKX63EGLCXZG6HX SBNQKZMBOI4SUK4MGAYZ4RKP52DMJBDOU4UCZRHEI5WTRPBWLF2XNJX2
Voter3 GC5TAMTUAMBTNP6RZS5CPPC3ZVAQEYWV5DYWLQPV4U5LO56OOQXYG6DZ SDGU62DH5OT7DQU64GXARHDPWMTNL6VYGDPJYYO4DBV2VCI5TILUURAU

Now we need to build the contract by going to root of the contract folder contracts/voting and execute:

$ soroban contract build

Then, optimise the wasm by:

$ cargo install soroban-cli --features opt
$ soroban contract optimize --wasm target/wasm32-unknown-unknown/release/voting.wasm
Reading: target/wasm32-unknown-unknown/release/lottery.wasm (6476 bytes)
Writing to: target/wasm32-unknown-unknown/release/lottery.optimized.wasm...
Optimized: target/wasm32-unknown-unknown/release/lottery.optimized.wasm (5089 bytes)

That will give us the needed wasm file under target/wasm32-unknown-unknown/release/voting.optimized.wasm we need to deploy:

$ soroban contract deploy \
--source SCXBOAMHMCLODJ6IAA55RPOHJWHQMXU6YUI24JUH6SEL7XHGDXOKK3RM \
--wasm target/wasm32-unknown-unknown/release/voting.optimized.wasm \
--rpc-url https://rpc-futurenet.stellar.org:443 \
--network-passphrase 'Test SDF Future Network ; October 2022'

CCNYMNCHVCAYGZK5566WINJPG4CTNMCIY4QTUN3FHYDE4FT4AANKXW2M

Now we need to initialise our voting contract. Lets invoke the init function of the contract:

soroban contract invoke \
--id CCNYMNCHVCAYGZK5566WINJPG4CTNMCIY4QTUN3FHYDE4FT4AANKXW2M \
--source SCXBOAMHMCLODJ6IAA55RPOHJWHQMXU6YUI24JUH6SEL7XHGDXOKK3RM \
--rpc-url https://rpc-futurenet.stellar.org:443 \
--network-passphrase 'Test SDF Future Network ; October 2022' \
-- \
init \
--admin GAH6O4LPMME6INTWXFS3IVZBGDSCN7KCSIAENUNDVQEJKT2D5ILLNYYR \
--voting_period_secs 3600 \
--target_approval_rate_bps 50000 \
--total_voters 3

Great ! we have our voting contract is initialised. Lets now create a sample proposal:

soroban contract invoke \
--id CCNYMNCHVCAYGZK5566WINJPG4CTNMCIY4QTUN3FHYDE4FT4AANKXW2M \
--source SCXBOAMHMCLODJ6IAA55RPOHJWHQMXU6YUI24JUH6SEL7XHGDXOKK3RM \
--rpc-url https://rpc-futurenet.stellar.org:443 \
--network-passphrase 'Test SDF Future Network ; October 2022' \
-- \
create_proposal \
--id 1

Notice we changed the --source param with the private key of admin . Although in this case doesn't matter too much, as anyone can create proposals. Then specified the --id to 1, as its the id of the proposal.

Now its time to vote !

soroban contract invoke \
--id CCNYMNCHVCAYGZK5566WINJPG4CTNMCIY4QTUN3FHYDE4FT4AANKXW2M \
--source SDMBPBRM4TY33SB7PJ3X46I4OOEAIP4LU4CGLX7DCWBJZH6BLEMQJHSB \
--rpc-url https://rpc-futurenet.stellar.org:443 \
--network-passphrase 'Test SDF Future Network ; October 2022' \
-- \
vote \
--voter GDASG2GN2FLMJEVPW423LW6UVVLZXNGLU7H5QR5IHAJCE3VWKSOSRRC6 \
--id 1

The above votes for player1. Notice we set the --source param to voter1 private key and --voter to voter1 pub key/address. This operation should be repeated per each voter who wants to approve the proposal. For this test, only voter1 and voter2 are going to vote, which means the proposal should be approved.

Lets check it, by inspecting events.

  1. Search in the laboratory for the latest transaction of voter2 .

  2. Events are part of the transaction output, and are stored in the result_meta_xdr field. We can just click on it and the laboratory will redirect us to the decoded content.

  3. Search in that page for "events" and something like this will appear:

  4. We can observe the number 6666 in the data field of the events, which idicates the approval rate in basic points. That means the proposal with id 1 has an approval rate of 66,66% or 2/3 of the total voters.

With the above tests we concluded this first version of the voting contract to work in futurenet.

geofmureithi commented 1 year ago

This issue has alot of knowledge, maybe it should be organized into some structured docs.