思维之海

——在云端,寻找我的星匙。

北斗UMA专项

北斗计划 - 天枢。A little bit of recordings during the UMA session.

References

Conflux

Conflux课程视频

forum.conflux.fun Conflux Forum,Homework & Resources

Lecture 1 - Introduction Of Blockchain

This part is the same as https://vel.life/区块链.

Lecture 2 - Cryptoeconomics 加密经济学

winner takes all

Blockchains and cryptocurrency will generate a new and better internet.

Token 通证

SoV: Store of Value; MoE: Media of Exchange.

NFTs: non-fungible tokens(非同质化通证),代表特定数字资产的特殊通证

DeFi: 一类携带投票权的token

Token Design

3 D’s of Token Design

s of Token Design

Conflux Token Economy 通证经济

The cryptoeconomic goals for Conflux were to:
● Attract users to actively use the network for value add services, and global ventures.
● Remove any barriers to entry for those making meaningful contributions
● Support security, stability, and predictability of the network

Key problem

  • Inefficient On-Chain Storage
    ● Ethereum users pay a one time fee at the time of including the code on chain, but the community bears the cost of keeping the contract in storage - much of the state-tree space on Ethereum is occupied by inactive smart contracts.
  • Wasted Computation
    ● BTC and ETH process blocks strictly one-by-one, creating a winner takes all characteristic for mining these chains, increasing the chance of forks.
  • Low Throughput
    ● Many PoW chains have a low TPS, and not suitable for payments.

Conflux Token (CFX)

Conflux’s unique native token is called CFX which is used for economic value transfers and payments for the cost of usage.

CFX was designed to serve as a:

  • Medium of Exchange (MoE)
  • Store of Value (SoV)
  • A unit of account for blockchain based data
  • Miner Incentives (compensation for processing new blocks)

CFX exists in two forms: Liquid and illiquid.

  • Liquid: they can be immediately transferred/used on Conflux
    Network.
  • Illiquid: Tokens are locked up (via staking) in three different forms:
    1) Staked to earn the user interest
    2) Bonded storage to purchase space on the network
    3) Locked up to purchase votes in network governance

Staking 权益制

Staking for Interest 利息

Conflux Network distributes interest on all tokens at a rate of 4% per year.

Staking for Storage Space 存储

A user who wants to use Conflux Network for smart contract execution needs to place a pre-defined number of tokens into a bonded storage.

Staking for Voting Rights 投票权

Conflux Network’s ecosystem fund in the future will transform into a DAO where Conflux stakeholders vote on operations using voting rights.

To cast a vote, users must lock up their tokens, where the time locked up determines the number of votes. Voting rights awarded according to:

Mining Rewards 挖矿奖励

Miners receive income from three sources:

  • Transaction User Fees: In the long term user fees will make the majority of miner income
  • Block Rewards: In the short term, block rewards will make the majority of miner income.
  • Interest Income: Interest on bonded storage tokens are given to miners.

Economy System

Adjust Miner revenue as function of adoption.

Real application is not living in a vacuum, but a complex and random world. That means we have to introduce some random mechanisms into the model.

Lecture 3 - Fundamental Concepts & Tools

从用户的角度理解区块链。

Resources

Accounts & Transactions 账户和交易

Digital signatures 数字签名

digital signatures are cryptographic tools and algorithms used to prove message authenticity and integrity

  • authenticity(真实性): the sender is who they claim to be
  • integrity(完整性): the message has not been modified

大多数区块链系统使用椭圆曲线密码学,即椭圆曲线数字签名算法ECDSA)。【非对称加密】

Wallets

Your identity is: your private-public keypair

钱包就是一个存储 identity 的容器。

js-conflux-sdk

read and run the full example

js-conflux-sdk documentation

Using the upfront 3 lines to install js-conflux-sdk@1.0.0-alpha.4(注意版本)。

Or if you have installed a WSL like me…

Newer version might have different actions.

1
2
3
4
$ mkdir conflux-playground
$ cd conflux-playground
$ npm install js-conflux-sdk@1.0.0-alpha.4
$ node # enter coding mode

Key & Address - Coding practice

This process is nearly impossible to do it backwards.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// import "js-conflux-sdk"
const util = require('js-conflux-sdk/src/util');

// generate a random private key
const privkey = util.sign.randomPrivateKey();
console.log('private key:', util.format.hex(privkey));

// derive public key from private key
const pubkey = util.sign.privateKeyToPublicKey(privkey);
console.log('public key:', util.format.hex(pubkey));

// derive address from public key
const address = util.sign.publicKeyToAddress(pubkey);
console.log('address:', util.format.hex(address));

sign a message using our private key

1
2
3
4
const Message = require('js-conflux-sdk/src/message');
const msg = new Message("Hello! Sincerely, Vel");
msg.sign(privkey);
console.log('signed message:', msg)

check message authenticity

检查信息是否被修改。

1
2
3
4
// const Message = require('js-conflux-sdk/src/message');
const assert = require('assert');
let recovered = Message.recover(msg.signature, msg.hash)
assert.equal(recovered, util.format.hex(pubkey))

tamper with message

1
2
3
4
console.log('message:', msg.message);
msg.message = "Hello! Sincerely, ----- Hacker";
recovered = Message.recover(msg.signature, msg.hash)
assert.notEqual(recovered, util.format.hex(pubkey))

full example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
const Account = require('js-conflux-sdk/src/account');
const assert = require('assert');
const { Conflux, Drip, Message, util } = require('js-conflux-sdk');

async function main() {
// ---- generate random private key ----
const privkey = util.sign.randomPrivateKey();
console.log('private key:', util.format.hex(privkey));

// ---- derive public key ----
const pubkey = util.sign.privateKeyToPublicKey(privkey);
console.log('public key:', util.format.hex(pubkey));

// ---- derive address ----
const address = util.sign.publicKeyToAddress(pubkey);
console.log('address:', util.format.hex(address));

// ---- sign message ----
const msg = new Message('Hello! Sincerely, Peter');
msg.sign(privkey);
console.log('signed message:', msg)

// ---- check signature ----
let recovered = Message.recover(msg.signature, msg.hash)
assert.strictEqual(recovered, util.format.hex(pubkey))

// ---- detect tampering using signature ----
msg.message = 'Hello! Sincerely, ----- Hacker';
recovered = Message.recover(msg.signature, msg.hash)
assert.notStrictEqual(recovered, util.format.hex(pubkey))

// ---- create and sign transaction ----
const local_account = new Account({ privateKey: util.format.hex(privkey) });

const tx = local_account.signTransaction({
from: util.format.hex(address),
to: util.format.hex(address),
value: Drip.fromCFX(10).toDrip(),
nonce: '0x00',
gasPrice: '0x00',
gas: '0x00',
storageLimit: '0x00',
epochHeight: '0x00',
});

console.log('transaction:', tx);
console.log('transaction hash:', tx.hash);

// ---- send transaction ----
const conflux = new Conflux({ url: 'http://mainnet-jsonrpc.conflux-chain.org:12537' });

// TODO: import your Conflux Portal wallet
// follow: Account Details, Export Private Key
// make sure to add a '0x' prefix to your private key
// make sure your account has sufficient balance
const account = conflux.Account({ privateKey: util.format.hex(privkey) });

// set recipient
const to = '0x145834072064DcD9B931237B5aEe217c241e3644';

// set value to send
const value = Drip.fromCFX(10).toDrip();

const epochHeight = await conflux.getEpochNumber();
const estimate = await conflux.estimateGasAndCollateral({ to, value });
const gasPrice = await conflux.getGasPrice();
const nonce = await conflux.getNextNonce(account.address);
const status = await conflux.getStatus();

const txHash = await account.sendTransaction({
to,
value,
nonce,
gasPrice,
gas: estimate.gasUsed,
storageLimit: estimate.storageCollateralized,
chainId: status.chainId,
data: null,
epochHeight,
});

console.log('sending transaction, hash:', txHash);

// wait 10 seconds
await new Promise(resolve => setTimeout(resolve, 10 * 1000));

// get transaction
const transaction = await conflux.getTransactionByHash(txHash);
console.log('transaction:', transaction);

// wait 10 seconds
await new Promise(resolve => setTimeout(resolve, 10 * 1000));

// get receipt
const receipt = await conflux.getTransactionReceipt(txHash);
console.log('receipt', receipt);
}

main()

Account

▸for each identity, there is a corresponding account maintained on the blockchain
▸the account captures a state at a given time: the current balance, the number of transactions sent, code, …
▸your address will not change (though you might have multiple addresses)
▸the account state associated to your address will change as you send and receive transactions


JSON-representation of a new account:

see: https://developer.conflux-chain.org/docs/conflux-doc/docs/json_rpc/#cfx_getaccount

1
2
3
4
5
6
7
8
9
{
"accumulatedInterestReturn": "0x0",
"admin": "0x0000000000000000000000000000000000000000",
"balance": "0x0",
"codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82...",
"collateralForStorage": "0x0",
"nonce": "0x0",
"stakingBalance": "0x0"
}

each account has a balance(CFX余额) associated with it.

nonce(交易数): number of accepted transactions from this account

SIMPLE PAYMENT TRANSACTIONS:

  • simply sending a number of coins (tokens) from one address to another
  • the sender signs the transaction using their private key
  • if you do not have my private key, you cannot send on my behalf

Transaction

JSON-representation of a transaction:

1
2
3
4
5
6
7
8
9
10
11
12
{
"from": "0x1dBDA5dD2e952914bC74a802510D0FA59F9d7636",
"to": "0x145834072064DcD9B931237B5aEe217c241e3644",
"value": "0x3635c9adc5dea00000",
"gas": "0x5208",
"gasPrice": "0x174876e800",
"nonce": "0x1",
"data": "0x",
"v": "0x1",
"r": "0x27e5cb110dd198b8fc963d4741ec0840400a6351d9e0c458eed...",
"s": "0x2c486d8e26da3c867fbcf4ab242af1265a5036c5e23ea42c8ab...",
}

from / to: payment transactions specify a sender and a receiver

value: you also need to specify how much you want to send(转账金额)

gas / gasPrice: you might need to pay for transaction(交易费)

nonce: nonce is the number of the transaction(交易号)

data: data is used for smart contract calls(用于智能合约)

SIGNATURE{v, r, s}: a transaction needs to be signed by the sender(签名)

transactions are identified by the transaction hash

1
0x53fe995edeec7d241791ff32635244e94ecfd722c9fe90f34ddf59082d814514

You can do queries like these:
▸ Check if transaction 0x53fe995 succeeded
▸ Find the sender address of transaction 0x53fe995
▸ Get the execution results of transaction 0x53fe995

Distributed ledger 分布式账本

Block 区块

a block is just a list of transactions (block body)
… plus some metadata (block header)

JSON-representation of a block:

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"hash": "0xc8f5310402330767adb624f436fa579ca3a6e28bb33f09ec...",
"miner": "0x1905c5723adf66f14f9a33d6d99263cb00c2992c",
"nonce": "0x30176787e0290260",
"parentHash": "0xb11d32edb8e8f09941000c898269f665d275342694...",
"epochNumber": "0x4bad97",
"refereeHashes": [ ... ],
"transactions": [
"0x0b5b3d8f542a3c830ec57b83c07d1282241712478edab3ba8e1a05...",
"0x96b46d10999cda47c4fda1dab7e8e29ce68f5b9ae2d707fde008c7...",
...
],
}

hash: just like txs, blocks are uniquely identified by their hashes

miner & nonce: some information about the creator of the block (see PoW)

parentHash / epochNumber / refereeHashes: information about the blocks position on our ledger

Blockchain

Tree-graph

Conflux uses a Tree-Graph ledger instead of a single chain

… this way, if two blocks are created simultaneously, the system can use both, thus increasing throughput and security

THE LEDGER OF CONFLUX — FURTHER READING

Smart contracts 智能合约

imagine that your mailbox has a machine inside that decides what to do with the coins

moreover, you can also pass it notes with instructions, not just coins

this machine can be unique to each box, built by its owner


JSON-representation of a smart contract transaction:

智能合约的两个特征:

  • to starts with an 8(normal contract starts with a 1
  • data field is not empty(某种方法签名)
1
2
3
4
5
6
7
8
9
10
11
12
{
"from": "0x1dBDA5dD2e952914bC74a802510D0FA59F9d7636",
"to": "0x8b017126d2fede908a86b36b43969f17d25f3770",
"value": "0x3635c9adc5dea00000",
"gas": "0x5208",
"gasPrice": "0x174876e800",
"nonce": "0x1",
"data": "0xa6f2ae3a",
"v": "0x1",
"r": "0x27e5cb110dd198b8fc963d4741ec0840400a6351d9e0c458eed...",
"s": "0x2c486d8e26da3c867fbcf4ab242af1265a5036c5e23ea42c8ab...",
}

transaction receipt 交易收据

JSON-representation of a receipt(收据):

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"from": "0xb2988210c05a43ebd76575f5421ef84b120ebf80",
"to": "0xb2988210c05a43ebd76575f5421ef84b120ebf80",
"transactionHash": "0x53fe995edeec7d241791ff32635244e94ecfd7..."
"epochNumber": 451990,
"blockHash": "0xbb1eea3c8a574dc19f7d8311a2096e23a39f12e649a...",
"index": 0,
"outcomeStatus": 0, // 0 means succeed
"contractCreated": null, // created successfully
"gasUsed": "0x5208",
"logs": [],
"logsBloom": "0x0000000000000000000000000000000000000000000...",
}

from / to / transactionHash: transaction info

epochNumber / blockHash / index: location on the ledger(对某些应用程序有用)

outcomeStatus / contractCreated / gasUsed / logs / logsBloom: execution results

Inspect data on the ledger

Conflux Scan(Blockchain Explorers)

blockchain explorers are data aggregators that you can use to query accounts, transactions, blocks, etc.

for Conflux, the official blockchain explorer is called Conflux Scanconfluxscan.io

Set up wallet & Send transactions

wallet’s usage

a keypair represents an identity on the blockchain

  • public key / address: your public identity
  • private key: your authorization to act on behalf of this identity

if you know an account’s private key, you can sign transactions from that account

  • storing keys securely is challenging even for experts

  • store private keys, create and sign transactions
  • connect to a blockchain node
  • send transactions into the system
  • monitor transaction and account state

Conflux Portal(Wallet)

Conflux Portal(portal.conflux-chain.org) is the wallet we will use for this course

it is a browser extension(浏览器扩展) available for all major browsers

it allows you to send simple transactions or even interact with smart contracts and dapps

Conflux Portal is based on MetaMask (Ethereum)

Create a wallet

  • first, we need to install the extension
  • during onboarding, we can choose whether we want to import and existing wallet or create a new one
  • the wallet will generate a private key and store it encrypted using a password you choose
  • instead of a hex string, you’ll see the private key as a mnemonic phrase — 12 English words

我们可以通过“存入”(Deposit)按钮来获取一些没有任何价值的免费代币。

完成后,截取message的tx字段(交易哈希值),将可以在Conflux Scan上搜索到相应的交易:

执行一笔转账交易:

Wallet Security 101

  • remember: if you lose your private key (seed phrase), no one will be able to recover your funds
  • remember: if someone gains access to your private key, they can (and will) steal your funds
  • best to backup seed phrase on a piece of paper or using a password manager
  • for higher security, use a hardware wallet

How to acquire tokens?

▸ get free test CFX on testnet or Oceanus through faucet

▸ earn CFX through mining (mining.confluxnetwork.org)

▸ earn FC through bounty (bounty.conflux-chain.org)

▸ earn FC through grants (grants.confluxnetwork.org)

▸ buy FC on moondex.io or other exchanges(if you have another digital currency like bitcoin)

Interactive map of Conflux nodes (confluxmap.com 5)

Interact with dapps(去中心化应用)

Demo:http://167.172.160.61

查询相应的智能合约交易记录:

Homework of Lecture 3

Lecture 3 - Homework & Resources

Homework is done by a group.

transaction classification

1)On which network is this transaction? 0xb97e091e42252571072ae9c605bda16c8f2568cb6a4ff8fd717d384123074b55

Conflux now have a test network(Conflux Testnet) , and a pre-mainnet network(Conflux Oceanus).

But none of those networks have the requested transaction.

2)Find a block with 20 or more transactions and send us the block hash.

0x618f924e1f6c7eab371551d8a5e407aeecd9a192bdd130204dc1ccc42566360f

note: this block is from the Conflux Testnet,and contains 280 transactions.

And there is a JS code to automatically find a block with 20 or more transactions:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
const { Conflux } = require('js-conflux-sdk');

async function main() {
// initalize a Conflux object
const cfx = new Conflux({
url: 'http://mainnet-jsonrpc.conflux-chain.org:12537',
defaultGasPrice: 100,
defaultGas: 1000000,
logger: console,
});
let epochStart = 7742635
let answer = false
for(var i = epochStart; i> 0; i--){
const blockArray = await cfx.getBlocksByEpochNumber(i)
for (block in blockArray) {
let result = await cfx.getBlockByHash(blockArray[block])
if (result['transactions'].length >=20 ) {
answer = result['hash']
break
}
}
if (answer) break
}
console.log('result is ' + answer)
}

main();

By running it, we can find the results: 0x273d13668462ae7cbb14f25fea0eb8bdbac2dfcd4571a3c5139f08a864d160ba

note: this block is from the Conflux Oceanus,and contains 22 transactions.

Here is the running test:

failed transaction

3)Try to find a failed transaction. Did the sender retry?

Failed First try:**0x6151cf6ceb0d2156e6f35c258d94e27ebc299d149ee664544db343c8e5d29520**

Failed Second try: 0x7635749799dafce791bb952d7a83859c1c4faca8f6cb3d2652fabb073a992241

Successful Third try:

0x6151cf6ceb0d2156e6f35c258d94e27ebc299d149ee664544db343c8e5d29520

Doing smart contract actually also has failed several transactions…

CFX faucet test

4)Create a wallet, get some CFX through the faucet and send us the corresponding transactions hash.

1
{"code":0,"message":{"tx":"0x0163755fe87b34053d2f949ba757b23f3fdbff47ac73b3b0af3e8fb2cabba2d4"}}

Use “Deposit” button to get free CFX~~

0x0163755fe87b34053d2f949ba757b23f3fdbff47ac73b3b0af3e8fb2cabba2d4

buy a ticket

5)Buy a ticket on 167.172.160.61 and send us the corresponding transaction hash.
5.1)What happens if you lower the gas limit before sending the transaction?
5.2)What happens if you try to buy a second ticket for the same address?

5)0xbc6e65773ce248c40743c4cbad6472284f3b2a2ab9ef6b86e1a2734b049c0248

5.1)there is a minimal gas limit:

When I lower the gas limit, I get a failed transaction: (Out of gas)

5.2)When I try to buy a second ticket for the same address, I get a failed transaction: (Execution error, maybe the smart contract constraints that one address can only buy one ticket)

On the contrary, if I choose to buy a second ticket from another account(address):(first, need unauthorize the website, and reconnect to choose another account)

query ticket purchases

6)Try querying recent ticket purchases. Has there been any?

Yes. Use the Purchase method: (And that "0x1e51d.. address is one of my account)

creator of the Tickets contract

7)Who is the creator of the Tickets contract?

First, use owner method to get an address:

Then search for the address:

This seems not what we want, so I track which account all the tokens are transferred into:

And…search, with two-step validation, I think I’ve found the creator of this contract:

  • most definitely 0x1dbda5dd2e952914bc74a802510d0fa59f9d7636

And I think 0x8B017126d2FEDe908a86B36b43969F17d25F3770 is the address of this contract. But I couldn’t be able to find any source code of the contract using Conflux Scan.

balance of this account

8)What is the balance of this account? How do you think this account acquired these tokens?

The creator’s address 0x1dbda5dd2e952914bc74a802510d0fa59f9d7636:

The contract’s address 0x8b017126d2fede908a86b36b43969f17d25f3770:

  • 330 CFX

    ▸people buy tickets from this address and send it 33 * 10 CFX (which means there are 33 tickets been sold)

the most FC tokens address

9)Which address holds the most FC tokens?

  1. the conflux system address
    1. System is responsible for 1:1 exchange of FC/CFX transactions
      1. In this scenario, the contract creator’s address 0x144aa8f554d2ffbc81e0aa0f533f76f5220db09c might have had the most FC tokens because this address is currently holding an enormous amount of CFX roughly about 999999996999988 CFX. That’s really something.
    2. System delivers FC tokens to all other users
    3. So in theory it should hold the most FC tokens
  2. 0x1878e9b8d2fec316a2e666485b927e92a3b4f43e
    1. This address holds 55999 FC tokens, and was involved in the first FC contract transaction
    2. Considering the total amount of FC tokens is about 4484424 FC tokens, this could also have a great chance to be the address that holds the most FC tokens

Lecture 4 - Introduction to Smart Contracts

Decentralized Applications Architecture

Traditional Web Applications (Web 2.0)

Web 2.0 uses the C/S model.

  • Enter domian, retrieve frontend through HTTP(S)
  • User interacts with the frontend which might send additional requests to the backend (dynamic content)
  • The backend could be a server cluster or a cloud, but the main logic remains the same

Decentalized Applications (Web 3.0)

Web 3.0 uses the P2P model (partly):

  • Get frontend from server
  • Frontend initiates transaction
  • User approves transaction
  • There might still be dynamic content
  • Backend can also query the blockchain

IPFS(星际文件系统):一个去中心化的文件存储系统。

Conflux Studio Overview

a 3rd-party IDE called Conflux Studio

Toolchain

we will use these tools
▸ Conflux Studio (v0.4.1) https://github.com/ObsidianLabs/ConfluxStudio/blob/master/README.md
▸ Docker (latest) https://www.docker.com/products/docker-desktop
▸ Solidity 7.1, solc (v0.7.1)
▸ Conflux Truffle (v.0.0.8)
▸ conflux-rust (v.0.6.3

Basic Usage

Docker的原理是在本地运行一个conflux节点,实际上整个网络都在本地,但只包含一个节点,所以非常适合本地开发。

下载课程的智能合约示例:https://github.com/Thegaram/cfx-uma-resources/raw/master/cfx-lecture-4-tickets.zip

在studio中打开上述项目,注意路径名不要有中文。

Writing Smart Contracts

The code that is executed is called EVM bytecode. We write contracts in higher-level languages, the most popular language used on Ethereum and Conflux is Solidity.

为智能合约专门设计的高级语言。

EVM bytecode:Ethereum Virtual Machine bytcode 以太坊虚拟机字节码

CVM:Conflux Virtual Machine(和EVM基本一致,智能合约的编写是兼容的)

example.sol :

1
2
3
4
5
6
7
8
9
10
11
12
13
// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.7.1;

contract ContractName {
uint256 number;
address owner;
mapping (address => uint256) counts; // 字典

function foo(uint256 value) public {
counts[owner] = value;
}
}

abi.json :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[
{
"name": "foo",
"type": "function"
"inputs": [
{
"internalType": "uint256",
"name": "val",
"type": "uint256"
}
],
"outputs": [],
"stateMutability": "nonpayable",
}
]

Tockets.sol

讲了讲怎么使用。。


introduction to dapps
ethereum.org/en/developers/docs/dapps

built on Ethereum — dapp examples
docs.ethhub.io/built-on-ethereum/built-on-ethereum

official Solidity 7.1 documentation
solidity.readthedocs.io/en/v0.7.1

learn X in Y minutes (where X=Solidity) warning! earlier Solidity version
learnxinyminutes.com/docs/solidity

Solidity by example warning! earlier Solidity version
solidity-by-example.org/0.6

CryptoZombies
cryptozombies.io


Conflux Studio overview
github.com/ObsidianLabs/ConfluxStudio/blob/master/README.md

dapp tutorial
github.com/ObsidianLabs/conflux-dapp-tutorial

Conflux frontend example project
github.com/ObsidianLabs/conflux-frontend-react


Solidity Security: Comprehensive list of known attack vectors and common anti-patterns
blog.sigmaprime.io/solidity-security.html
github.com/zxhubo/Knowledge-Base

the Ethernaut (by OpenZeppelin)
ethernaut.openzeppelin.com

Homework of Lecture 4

Lecture 4 - Homework & Resources

Homework is done by a group.

Conflux Studio

3.1 Basic usage of Conflux Studio

Download and install Conflux Studio and all the components required.

Done.

Download the Tickets project from the lecture (https://github.com/Thegaram/cfx-uma-resources/raw/master/cfx-lecture-4-tickets.zip) and import it into Conflux Studio.

Done.

Deploy an instance of the contract on Conflux Oceanus (hint: you can send CFX from your Conflux Portal account to your Conflux Studio account).

get CFX from faucet: wallet.confluxscan.io/faucet/dev/ask?address={address}

To make sure the deploying account has enough CFXs to pay transaction fees.

Or (send CFX from your Conflux Portal account to your Conflux Studio account)

And Deploy~

Buy a ticket from another account. Validate the ticket with the owner. Withdraw the profits.

First, find the contract we deployed, which leads us to the contract method’s panal:

s panal

And we just buy, validate, and withdraw.

Send us the address of the contract, the 4 transaction hashes (deploy, buy(), validate(), withdraw()), and screenshots of how you sent them from Conflux Studio.

deploy: 0x1c5d87cbc299df5f2d5f07d989e2df83ebca253838edb0836b86d24587b72878

buy: 0xcfbdf3ae39291ea42c85142e18514d4d7329a88057fa8811f043a7869619bcb6

validate: 0xe4e4dbbc708a7e5e5272e8323d124052297ed4dd6ae772da8b2bc9a416b0f2d7

withdraw: 0x367034b42d8cce63f19cf585b3644587e084f8456fd3a562f223dfdd7341c3f9

Tickets.sol

3.2 Customizing Tickets.sol

Update Ticket.sol so that it becomes possible to set the number of tickets and the price per ticket when you deploy a contract.

For instance, for event A, I want to sell 10 tickets of 100 CFX each. For event B, I want to sell 1000 tickets for 2 CFX each.

Test your solution on a local development network.

Send us the source code and a screenshot of deploying a contract with 33 tickets for 44 CFX each.

Just set a few constructor’s parameters and all is OK.

1
2
3
4
5
constructor(uint256 tickets, uint256 price) {
owner = msg.sender;
num_tickets = tickets;
price_drips = price * 1e18;
}

Then we get a panal with adjustable number of tickets and price for each.

Send the transaction, and check:

Buy tickets

+1. Buying multiple tickets from one address [OPTIONAL]

Update Tickets.sol so that one user can buy multiple tickets. For instance, Bob might want to buy 2 tickets, one for himself and one for his girlfriend.

Test your solution on a local development network.

Send us the source code and some screenshots of buying 2 or more tickets from an address and then validating them.

Source code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.7.1;

contract Tickets {
address public owner;

uint256 public num_tickets = 100;
uint256 public price_drips = 10 * 1e18; // 10 CFX
mapping (address => uint256) public has_ticket;

event Validated(address visitor, uint256 tickets);

constructor(uint256 tickets, uint256 price) {
owner = msg.sender;
num_tickets = tickets;
price_drips = price * 1e18;
}

// buy ticket
function buy(uint256 tickets) public payable {
// check tickets
require(num_tickets > 0 && tickets <= num_tickets && tickets > 0, "TICKETS: illegal operation");

// check if the buying price is correct
require(msg.value == tickets * price_drips, "TICKETS: incorrect amount");

// successful buy
if( has_ticket[msg.sender] != 0 )
has_ticket[msg.sender] += tickets;
else
has_ticket[msg.sender] = tickets;
num_tickets -= tickets;
}

// validate ticket
function validate(address visitor) public {
require(msg.sender == owner, "TICKETS: unauthorized");
require(has_ticket[visitor] > 0, "TICKETS: visitor has no ticket");

uint256 tickets = has_ticket[visitor];
has_ticket[visitor] = 0;
emit Validated(visitor, tickets);
}

// withdraw profit
function withdraw() public {
require(msg.sender == owner, "TICKETS: unauthorized");
uint256 profit = address(this).balance;
msg.sender.transfer(profit);
}
}

We set tickets_num to 2333, and price to 1 CFX. (And buy 5 tickets.)

buying 2 or more tickets from an address:

validating them:

Time of the event

+1. Time of the event [OPTIONAL]

Update Tickets.sol so that the organizer can set the time of the event.

Allow users to buy tickets up to 2 hours before the event. E.g. if the event is on 2020.12.01 19:00, you cannot buy tickets after 2020.12.01 17:00.

Allow the organizer to withdraw the profits 1 day after the event. E.g. if the event is on 2020.12.01 19:00, the organizer cannot withdraw the profits before 2020.12.02 19:00.

Hints:

Source code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.7.1;

contract Tickets {
address public owner;

uint256 public num_tickets = 100;
uint256 public price_drips = 10 * 1e18; // 10 CFX
uint256 public start;
mapping (address => uint256) public has_ticket;

event Validated(address visitor, uint256 tickets);

constructor(uint256 tickets, uint256 price, uint256 upcoming_days_of_the_event) {
owner = msg.sender;
num_tickets = tickets;
price_drips = price * 1e18;
start = upcoming_days_of_the_event * 1 days + block.timestamp;
}

// buy ticket
function buy(uint256 tickets) public payable {
// check time
require(block.timestamp <= start - 2 hours, "TICKETS: can't but due to time reasons");

// check tickets
require(num_tickets > 0 && tickets <= num_tickets && tickets > 0, "TICKETS: illegal operation");

// check if the buying price is correct
require(msg.value == tickets * price_drips, "TICKETS: incorrect amount");

// successful buy
if( has_ticket[msg.sender] != 0 )
has_ticket[msg.sender] += tickets;
else
has_ticket[msg.sender] = tickets;
num_tickets -= tickets;
}

// validate ticket
function validate(address visitor) public {
require(msg.sender == owner, "TICKETS: unauthorized");
require(has_ticket[visitor] > 0, "TICKETS: visitor has no ticket");

uint256 tickets = has_ticket[visitor];
has_ticket[visitor] = 0;
emit Validated(visitor, tickets);
}

// withdraw profit
function withdraw() public {
require(msg.sender == owner, "TICKETS: unauthorized");

require(block.timestamp >= start + 1 days, "TICKETS: can't withdraw due to time reasons");

uint256 profit = address(this).balance;
msg.sender.transfer(profit);
}
}

Set the start time as 3 days later:

Let’s buy some tickets and test if we can withdraw the money ahead of schdule:

Now we can see:

Transaction reverted

data TICKETS: can’t withdraw due to time reasons