3.23 vchain原始碼分析1
在做vechain智慧合約原始碼分析之前,我們先來看一下它的簡介
一、專案名稱
VeChain(VEN)
二、專案定位
全球領先的區塊鏈商品和資訊平臺
三、專案簡評
專案旨在解決商業社會中產品的資訊和信任問題,利用區塊鏈做高附加值產品的防偽追朔系統,基於此打造信任商業的生態體系。
四、專案願景
vechain的目標其實就是應用區塊鏈技術構造一個既可以自我迴圈、也可以向外擴充的可信任分散式商業生態環境。
接下來 我們直接通過它的智慧合約程式碼來仔細瞭解一下它的內部實現細節
首先是第一部分合約程式碼:
pragma solidity ^0.4.11;
// 許可權控制合約
contract Owned {
address public owner;
function Owned() {
owner = msg.sender;
}
// 許可權控制修飾符
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
function setOwner(address _newOwner) onlyOwner {
owner = _newOwner;
}
}
/**
* @title SafeMath
* @dev Math operations with safety checks that throw on error
*/
// 數學安全函式
library SafeMath {
function mul(uint256 a, uint256 b) internal constant returns (uint256) {
uint256 c = a * b;
assert(a == 0 || c / a == b); // 判斷 a不能為0 C/A不能等於b(防止造成gas浪費)
return c;
}
function div(uint256 a, uint256 b) internal constant returns (uint256) {
// assert(b > 0); // Solidity automatically throws when dividing by 0
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
function sub(uint256 a, uint256 b) internal constant returns (uint256) {
assert(b <= a); // 預防溢位
return a - b;
}
function add(uint256 a, uint256 b) internal constant returns (uint256) {
uint256 c = a + b;
assert(c >= a); // 節省gas
return c;
}
function toUINT112(uint256 a) internal constant returns(uint112) {
assert(uint112(a) == a); // 預防溢位
return uint112(a);
}
function toUINT120(uint256 a) internal constant returns(uint120) {
assert(uint120(a) == a); // 預防溢位
return uint120(a);
}
function toUINT128(uint256 a) internal constant returns(uint128) {
assert(uint128(a) == a); // 預防溢位
return uint128(a);
}
}
// Abstract contract for the full ERC 20 Token standard
// https://github.com/ethereum/EIPs/issues/20
// 抽象合約
contract Token {
/* This is a slight change to the ERC20 base standard.
function totalSupply() constant returns (uint256 supply);
is replaced with:
uint256 public totalSupply;
This automatically creates a getter function for the totalSupply.
This is moved to the base contract since public getter functions are not
currently recognised as an implementation of the matching abstract
function by the compiler.
*/
/// total amount of tokens
//uint256 public totalSupply;
function totalSupply() constant returns (uint256 supply); // 總髮行量
/// @param _owner The address from which the balance will be retrieved
/// @return The balance
function balanceOf(address _owner) constant returns (uint256 balance); // 查詢餘額
/// @notice send `_value` token to `_to` from `msg.sender`
/// @param _to The address of the recipient
/// @param _value The amount of token to be transferred
/// @return Whether the transfer was successful or not
function transfer(address _to, uint256 _value) returns (bool success); // 轉賬
/// @notice send `_value` token to `_to` from `_from` on the condition it is approved by `_from`
/// @param _from The address of the sender
/// @param _to The address of the recipient
/// @param _value The amount of token to be transferred
/// @return Whether the transfer was successful or not
function transferFrom(address _from, address _to, uint256 _value) returns (bool success); // 指定源地址轉向指定目標地址
/// @notice `msg.sender` approves `_addr` to spend `_value` tokens
/// @param _spender The address of the account able to transfer the tokens
/// @param _value The amount of wei to be approved for transfer
/// @return Whether the approval was successful or not
function approve(address _spender, uint256 _value) returns (bool success); // 允許量值設定
/// @param _owner The address of the account owning tokens
/// @param _spender The address of the account able to transfer the tokens
/// @return Amount of remaining tokens allowed to spent
function allowance(address _owner, address _spender) constant returns (uint256 remaining); // 允許指定地址提取的餘額
event Transfer(address indexed _from, address indexed _to, uint256 _value); // 轉賬事件
event Approval(address indexed _owner, address indexed _spender, uint256 _value); // approve 事件
}
/// VEN token, ERC20 compliant
contract VEN is Token, Owned {
using SafeMath for uint256; // 附著庫使用
string public constant name = "VeChain Token"; //The Token's name 代幣名稱
uint8 public constant decimals = 18; //Number of decimals of the smallest unit 精度
string public constant symbol = "VEN"; //An identifier 標識(符號)
// packed to 256bit to save gas usage.
// 打包為256位以節省gas
struct Supplies {
// uint128's max value is about 3e38.
// it's enough to present amount of tokens
uint128 total; // 總量
uint128 rawTokens;
}
Supplies supplies;
// Packed to 256bit to save gas usage.
// 打包成256位以節省gas
struct Account {
// uint112's max value is about 5e33.
// it's enough to present amount of tokens
uint112 balance;
// raw token can be transformed into balance with bonus
// 原始token 可以轉移到balance中
uint112 rawTokens;
// safe to store timestamp
uint32 lastMintedTimestamp; // 區塊時間
}
// Balances for each account
mapping(address => Account) accounts; // 指定地址的餘額
// Owner of account approves the transfer of an amount to another account
// 賬戶所有者所允許轉到另一個地址的金額
mapping(address => mapping(address => uint256)) allowed;
// bonus that can be shared by raw tokens
uint256 bonusOffered; // 獎勵
// Constructor
function VEN() {
}
// 總髮行量
function totalSupply() constant returns (uint256 supply){
return supplies.total;
}
// Send back ether sent to me
// 回退函式
function () {
revert(); // 將ether返還
}
// If sealed, transfer is enabled and mint is disabled
function isSealed() constant returns (bool) {
return owner == 0;
}
// 最近一次區塊生成時間
function lastMintedTimestamp(address _owner) constant returns(uint32) {
return accounts[_owner].lastMintedTimestamp;
}
// Claim bonus by raw tokens
function claimBonus(address _owner) internal{
require(isSealed());
if (accounts[_owner].rawTokens != 0) {
uint256 realBalance = balanceOf(_owner); // 真實的餘額
// 獎勵
uint256 bonus = realBalance
.sub(accounts[_owner].balance)
.sub(accounts[_owner].rawTokens); // 獲取獎勵
accounts[_owner].balance = realBalance.toUINT112();
accounts[_owner].rawTokens = 0;
if(bonus > 0){
Transfer(this, _owner, bonus);
}
}
}
// What is the balance of a particular account?
function balanceOf(address _owner) constant returns (uint256 balance) {
if (accounts[_owner].rawTokens == 0)
return accounts[_owner].balance;
if (bonusOffered > 0) {
uint256 bonus = bonusOffered
.mul(accounts[_owner].rawTokens)
.div(supplies.rawTokens);
return bonus.add(accounts[_owner].balance)
.add(accounts[_owner].rawTokens);
}
return uint256(accounts[_owner].balance)
.add(accounts[_owner].rawTokens);
}
// Transfer the balance from owner's account to another account
// 轉賬
function transfer(address _to, uint256 _amount) returns (bool success) {
require(isSealed());
// implicitly claim bonus for both sender and receiver
claimBonus(msg.sender);
claimBonus(_to);
// according to VEN's total supply, never overflow here
if (accounts[msg.sender].balance >= _amount
&& _amount > 0) {
accounts[msg.sender].balance -= uint112(_amount);
accounts[_to].balance = _amount.add(accounts[_to].balance).toUINT112();
Transfer(msg.sender, _to, _amount);
return true;
} else {
return false;
}
}
// Send _value amount of tokens from address _from to address _to
// The transferFrom method is used for a withdraw workflow, allowing contracts to send
// tokens on your behalf, for example to "deposit" to a contract address and/or to charge
// fees in sub-currencies; the command should fail unless the _from account has
// deliberately authorized the sender of the message via some mechanism; we propose
// these standardized APIs for approval:
function transferFrom(
address _from,
address _to,
uint256 _amount
) returns (bool success) {
require(isSealed());
// implicitly claim bonus for both sender and receiver
claimBonus(_from);
claimBonus(_to);
// according to VEN's total supply, never overflow here
if (accounts[_from].balance >= _amount
&& allowed[_from][msg.sender] >= _amount
&& _amount > 0) {
accounts[_from].balance -= uint112(_amount);
allowed[_from][msg.sender] -= _amount;
accounts[_to].balance = _amount.add(accounts[_to].balance).toUINT112();
Transfer(_from, _to, _amount);
return true;
} else {
return false;
}
}
// Allow _spender to withdraw from your account, multiple times, up to the _value amount.
// If this function is called again it overwrites the current allowance with _value.
function approve(address _spender, uint256 _amount) returns (bool success) {
allowed[msg.sender][_spender] = _amount;
Approval(msg.sender, _spender, _amount);
return true;
}
/* Approves and then calls the receiving contract */
function approveAndCall(address _spender, uint256 _value, bytes _extraData) returns (bool success) {
allowed[msg.sender][_spender] = _value;
Approval(msg.sender, _spender, _value);
//call the receiveApproval function on the contract you want to be notified. This crafts the function signature manually so one doesn't have to include a contract in here just for this.
//receiveApproval(address _from, uint256 _value, address _tokenContract, bytes _extraData)
//it is assumed that when does this that the call *should* succeed, otherwise one would use vanilla approve instead.
//if(!_spender.call(bytes4(bytes32(sha3("receiveApproval(address,uint256,address,bytes)"))), msg.sender, _value, this, _extraData)) { revert(); }
ApprovalReceiver(_spender).receiveApproval(msg.sender, _value, this, _extraData);
return true;
}
function allowance(address _owner, address _spender) constant returns (uint256 remaining) {
return allowed[_owner][_spender];
}
// Mint tokens and assign to some one 鑄幣
function mint(address _owner, uint256 _amount, bool _isRaw, uint32 timestamp) onlyOwner{
if (_isRaw) {
accounts[_owner].rawTokens = _amount.add(accounts[_owner].rawTokens).toUINT112();
supplies.rawTokens = _amount.add(supplies.rawTokens).toUINT128();
} else {
accounts[_owner].balance = _amount.add(accounts[_owner].balance).toUINT112();
}
accounts[_owner].lastMintedTimestamp = timestamp;
supplies.total = _amount.add(supplies.total).toUINT128();
Transfer(0, _owner, _amount);
}
// Offer bonus to raw tokens holder 給代幣持有者提供獎勵
function offerBonus(uint256 _bonus) onlyOwner {
bonusOffered = bonusOffered.add(_bonus);
supplies.total = _bonus.add(supplies.total).toUINT128();
Transfer(0, this, _bonus);
}
// Set owner to zero address, to disable mint, and enable token transfer
function seal() onlyOwner {
setOwner(0);
}
}
contract ApprovalReceiver {
function receiveApproval(address _from, uint256 _value, address _tokenContract, bytes _extraData);
}
-
學院Go語言視訊主頁
https://edu.csdn.net/lecturer/1928 -
掃碼獲取海量視訊及原始碼 QQ群:721929980
相關文章
- 3.24 vchain原始碼分析2AI原始碼
- 集合原始碼分析[1]-Collection 原始碼分析原始碼
- Leveldb原始碼分析--1原始碼
- MYSQL原始碼分析1MySql原始碼
- 介面1原始碼分析原始碼
- linux原始碼分析1Linux原始碼
- 原始碼分析系列1:HashMap原始碼分析(基於JDK1.8)原始碼HashMapJDK
- 【JDK】JDK原始碼分析-AbstractQueuedSynchronizer(1)JDK原始碼
- 3.21以太貓原始碼分析1原始碼
- JDK 原始碼分析(1) Object類JDK原始碼Object
- AFL二三事 -- 原始碼分析 1原始碼
- EOS原始碼分析(1)安裝原始碼
- Architecture(1)AsyncTask原始碼分析原始碼
- 神奇的 BlocksKit(1):原始碼分析BloC原始碼
- 原始碼分析axios(1)~原始碼分析、模擬axios的建立原始碼iOS
- Android 原始碼分析之旅3 1 訊息機制原始碼分析Android原始碼
- k8s client-go原始碼分析 informer原始碼分析(1)-概要分析K8SclientGo原始碼ORM
- Java容器類框架分析(1)ArrayList原始碼分析Java框架原始碼
- newrelic python agent 原始碼分析-1Python原始碼
- 重拾RunLoop之原始碼分析1OOP原始碼
- rxjs 原始碼分析1-(fromEvent)JS原始碼
- web.py原始碼分析: 模板(1)Web原始碼
- LibRTMP原始碼分析 1:解析URL原始碼
- iOS開發原始碼閱讀篇--FMDB原始碼分析1(FMResultSet)iOS原始碼
- SQLMAP原始碼分析Part1:流程篇SQL原始碼
- SpringMVC原始碼分析1:SpringMVC概述SpringMVC原始碼
- Netty Pipeline原始碼分析(1)Netty原始碼
- Java集合乾貨1——ArrayList原始碼分析Java原始碼
- Retrofit原始碼分析三 原始碼分析原始碼
- 集合原始碼分析[2]-AbstractList 原始碼分析原始碼
- 集合原始碼分析[3]-ArrayList 原始碼分析原始碼
- Guava 原始碼分析之 EventBus 原始碼分析Guava原始碼
- 3.23
- [原始碼分析] Facebook如何訓練超大模型---(1)原始碼大模型
- Element原始碼分析系列1一Layout(佈局)原始碼
- 原始碼分析三:OkHttp(1)—總體架構原始碼HTTP架構
- skynet原始碼分析(1)--模組載入原始碼
- btcpool礦池原始碼分析(1)環境搭建TCP原始碼