Authpaper Sales Smart Contract Part 1 Designing the System

In 2019 token sales, Authpaper uses smart contract to sell tokens to supporters. Good thing is that the sales process is simple, transparent and automatic. People only need to use their ERC-20 wallets to pay to the smart contract and receive tokens automatically.

However, smart contract alone is not enough. It is because there is a marketing campaign on the token sales to reward supporters who promote this project to others. In this series of articles, we will discuss the design and code of the token sales mechanism and related smart contract in details.

For those who wants quick answer, here is the smart contract code: https://github.com/SolonAuthpaper/AUPC_sales_contract

First, let us discuss the token sales details and marketing campaign.

The basic price of token is 0.001 ETH, minimum purchase is 0.1 ETH (100 AUPC). 62.5%, or 250M, AUPC will be sold to the public, and 12.5%, or 50M, AUPC will be allocated for the marketing referral program. The sales period is 10 Mar to 15 Aug.

The marketing referral program is inspired by a multi-level marketing solution built for a client. In this program, supporters get discounts when purchasing AUPC if they have referrer. The discount depends on the level of referral.

If your referral is on the top, you will have 5% discount. Two levels referral will have 5% + 3% = 8% discount, three levels will have 10% discount. Any additional levels will have additional 1% discount. The maximum discount is 15%.

For example, if Alice registers this program with referral from Bob, and Bob does not have referral from anyone when register, Alice can buy AUPC at price 0.001 * 95% = 0.00095 ether. Suppose Bob has referral from Charles, who also has referral from Dennis and so on, up to the seventh referral. There are seven levels of referral, so Alice will have 5 + 3 + 2 + 4 * 1 = 14% discount. She can buy AUPC in 0.00086 ether.

Besides, if the first three levels referrers are holding AUPC at the time of purchase, they will be awarded AUPC and ether as present. The first level will have 10% token and 5% ether of the purchased amount, the second level will have 6% token and 3% ether, the third level will have 4% token and 2% ether.

Suppose Alice has paid 0.86 ether and received 1000 AUPC. Bob will receive 100 AUPC and 0.043 ether as present, Charles will have 60 AUPC and 0.0258 ether, and Dennis will have 40 AUPC and 0.0172 ether.

It is infeasible to do the token sales manually, especially with this marketing program. The problem is:

Which part of the system should be in smart contract? Which should not?

First of all, it should not be done completely by smart contract. It is because the size of smart contract is limited (EIP-170) and most people are not familiar with calling smart contract with inputs. (We cannot limit our target supporters to those who know smart contract, right?)

Hence, the membership and referral inserting part must be done on website. On the other hand, all ethers payments and AUPC distributions must be done by smart contract. Hence, there is a need for smart contract to read data from our web server. The token purchase process now is:

  1. User registers information (including wallet and referral) on website. 
    He / She can read the discount information after login.
  2. User pays ETH to the smart contract, just like paying to a normal user.
  3. Smart contract will send an asymmetric request to website to get the level of referrals and referrers (top three levels) information. At this time the ETH is received but AUPC is not sent out yet.
  4. Smart contract receive data from server as a transaction.
  5. With this information, smart contract calculates the discount and number of AUPC the purchaser and referrers should get.
  6. Smart contract sends out AUPC and ETH to the parties.

By this setting, no special knowledge is required to purchase the token. One just register on website, pay ETH to smart contract. After that everything is done automatically and AUPC is sent out.

After designing, it is time to understand some basic code.

The server part is a standard membership system with a simple registration form and membership page. No special function is needed.

For the smart contract, it is written in Solidity. Solidity is based on Javascript and each contract is basically an object (contract) with different function.

Basically a smart contract is like (using Remix online IDE):

The first line defines the compiler version, which I recommend to use the latest one. Each contract is enclosed as a contract object. Like Javascript, one can define variables and functions inside a contract. Unlike Javascript, you need to define the type of the variables and the scopes of the functions.

There are some common types of variables. Address, which defines a contract or wallet address. Address payable is an address which you can call transfer function to transfer ETH to them. uint8, uint256, uint are unsigned integer with different memory size. Remember in Solidity there is no float numbers, only integers, and different integers cannot be operated together directly. bool is Boolean values. bytes32 is a series of 32 bit bytes and bytes is a series of bytes. string is string.

Data structure like array, list, dictionary are not exist. There is only one structure mapping. Mapping allows you to define mapping between two types. For example mapping (address => uint) public payedETH defines a mapping payedETH, which use address as index and uint as value.

By default, the variables are private, only the variables with public scope can be read publicly. The variables cannot be set directly.

There is a special type of variable, msg. msg is a variable keeping the information related to the node calling the function. msg.sender returns the address of the function caller. Notice that if the function calls another contract, the sender value will be the address of the first function contract, not the address calling the first function. msg.value shows the number of ETH sent with the call. Notice that msg.value is stored in wei, so 1 ETH is stored as 1* 10¹⁸, or 1 * 10 ** 18 in code. To make things easy, one can use “x ether” to represents x ETH in code. Float values like 0.1 ETH can be written as 100 finney.

There are different possible scopes of a function. public and external can be called by as public methods. Internal means the function can only be called by functions inside the contracts. One can add additional parameters payable and pure to indicate the function will do ETH transfer and will not change variables in the contract. These parameters are very important. Without payable parameter no ETH transfer can be done in a function. Pure parameter greatly reduces the cost of running the function, as the cost also depends on how much data is changed in the function.

You can define input and output parameters of a function like:

function strConcating(string memory _a, string memory _b) internal pure returns (string memory){ }

There are two kinds of special functions, constructor() and function()

constructor() is called when the contract is created, just like Object constructor in object oriented programming (OOP). As variables can be predefined, constructor is usually used to read the contract owner information.

function() is the fallback function of a contract, it is the only function without a name. Whenever someone sends ETH to the contract without calling any function, this function is called. If this function is not declared, when people accidentally send ETH to the contract. The contract will keep the ETH without running any code. If the programmer has not prepared any method to extract ETH from a contract, those ETH is essentially frozen forever. So remember to write this function.

In the next article, we will discuss the functions of the smart contract in details.