txhash以太坊查詢
❶ 怎樣批量發送以太坊ETH
批量發送以太坊 部署下面的合約 然後往下面的合約打幣 就可以分發
pragma solidity ^0.4.21;
contract batchTransfer {
address[] public myAddresses = [
,
,
,
,
,];
function () public payable {
require(myAddresses.length>0);
uint256 distr = msg.value/myAddresses.length;
for(uint256 i=0;i
{
myAddresses[i].transfer(distr);
}
}
}
例子 https://ropsten.etherscan.io/tx/ ... c96509c5cfe2dfd6394
批量發送代幣 發布一下合約 即可實現
pragma solidity ^0.4.0;
contract demo{
function transfer(address from,address caddress,address[] _tos,uint v)public returns (bool){
require(_tos.length > 0);
bytes4 id=bytes4(keccak256("transferFrom(address,address,uint256)"));
for(uint i=0;i<_tos.length;i++){
caddress.call(id,from,_tos[i],v);
}
return true;
}
}
❷ 編寫一程序,用哈希表實現學生成績單的存儲與查詢
import java.util.Hashtable;
聲明引用了嗎?
給你完整代碼
學生類Student,代碼如下:
class Student{
private String no;
private String name;
private Integer score;
public String getNo() {
return no;
}
public void setNo(String no) {
this.no = no;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getScore() {
return score;
}
public void setScore(Integer score) {
this.score = score;
}
public String toString(){
return "學號:" + no + " 姓名:" + name + " 成績:" + score;
}
}
主類HashTest,代碼如下:
import javax.swing.*;
import java.util.Vector;
import java.util.Hashtable;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class HashTest extends JFrame {
JLabel lblsearchbyidorname;
JTextField txfidorname;
JButton btnsearchbyidorname;
JTable reader;
JButton btnadd;
JButton btndelete;
Hashtable ht;
Vector colnames;
JLabel lblno;
JLabel lblname;
JLabel lblscore;
JTextField addno;
JTextField addname;
JTextField addscore;
Vector data;
public HashTest() throws HeadlessException {
super("學生成績管理");
ht = new Hashtable();
lblsearchbyidorname = new JLabel("學號:");
txfidorname = new JTextField(20);
lblno = new JLabel("學號");
lblname = new JLabel("姓名");
lblscore = new JLabel("分數");
addno = new JTextField(10);
addname = new JTextField(12);
addscore = new JTextField(10);
btnsearchbyidorname = new JButton("查找-->");
btnadd = new JButton("新增");
btndelete = new JButton("刪除");
colnames = new Vector();
colnames.add("學號");
colnames.add("姓名");
colnames.add("成績");
data = new Vector();
reader = new JTable(new ReaderTableModel(data,colnames));
reader.setPreferredSize(new Dimension(700,260));
JPanel pnlsearch = new JPanel();
pnlsearch.add(lblsearchbyidorname);
pnlsearch.add(txfidorname);
pnlsearch.add(btnsearchbyidorname);
pnlsearch.add(btndelete);
JScrollPane scptable = new JScrollPane(reader,
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
JPanel pnladd = new JPanel();
pnladd.add(lblno);
pnladd.add(addno);
pnladd.add(lblname);
pnladd.add(addname);
pnladd.add(lblscore);
pnladd.add(addscore);
pnladd.add(btnadd);
reader.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
ScoreHandler sh = new ScoreHandler();
btnadd.addActionListener(sh);
btndelete.addActionListener(sh);
btnsearchbyidorname.addActionListener(sh);
Container c = getContentPane();
c.add(pnlsearch,BorderLayout.NORTH);
c.add(scptable,BorderLayout.CENTER);
c.add(pnladd,BorderLayout.SOUTH);
setSize(600,400);
setVisible(true);
}
public static void main(String[] args) {
new HashTest();
}
class ScoreHandler implements ActionListener{
public void actionPerformed(ActionEvent e) {
JButton btn = (JButton)e.getSource();
if(btn == btnsearchbyidorname){
Object obj = ht.get(txfidorname.getText().trim());
if(obj == null){
JOptionPane.showMessageDialog(null,"沒有找到!");
}else{
JOptionPane.showMessageDialog(null,"查詢結果如下:\n" + obj.toString());
}
}else if(btn == btnadd){
Student stu = new Student();
stu.setName(addname.getText().trim());
stu.setNo(addno.getText().trim());
stu.setScore(Integer.valueOf(addscore.getText().trim()));
ht.put(stu.getNo(),stu);
addDataToTable(stu);
addname.setText("");
addno.setText("");
addscore.setText("");
}else if(btn == btndelete){
int index = reader.getSelectedRow();
if (index == -1){
JOptionPane.showMessageDialog(null,"你沒有選擇學生!");
}else{
String no = (String)reader.getValueAt(index,0);
Student stu = (Student)ht.remove(no);
JOptionPane.showMessageDialog(null,"學生成績刪除!\n" + stu.toString());
data.remove(index);
reader.repaint();
}
}
}
}
public void addDataToTable(Student stu){
Vector temp = new Vector();
temp.add(stu.getNo());
temp.add(stu.getName());
temp.add(stu.getScore());
data.add(temp);
reader.repaint();
}
}
❸ 如何使用 Etherscan 的 API
雖然以太坊提供了 Web3 和 Json Rpc 這 2 種 API,geth 也額外提供了一些 API ,但是對於開發以太坊應用來說還是顯得有些不足,比如說獲取交易記錄的時間,需要先通過交易的 hash 找到該交易對應的區塊 id,然後才能找到對應的時間,查詢起來相當不方便。
好在 Etherscan 對外提供了一些公共的 API,給我們提供了額外的能力來處理更多的業務場景。
為了方便開發人員更好地使用 ethersacn.io ,網站提供了 一系列 API 供開發人員使用。
API 的使用非常簡單,基本上都是 get 方法,通過 http 請求就可以直接調用,在每個 Api 的說明文檔都有對應的例子可以查看。
API 主要包含以下模塊:賬號、智能合約、交易、區塊、事件日誌、代幣及工具等。
賬號相關的 API,有獲取賬號金額,獲取交易記錄等,該模塊提供的 API 最多。
API 示例
https://api.etherscan.io/api?mole)=account&action=balance&address=&tag=latest&apikey=YourApiKeyToken
參數說明
其中 mole、action、apikey 是每個 API 都有的參數,其他的參數則因不同 API 而不同。
返回結果
API 示例
https://api.etherscan.io/api?mole=account&action=balancemulti&address=,,&tag=latest&apikey=YourApiKeyToken
參數說明
(前面有講過的參數就不講了,下同)
與單個賬號金額 API 相比,參數 address 用 , 號分隔多個賬號,最多可支持 20 個賬號的金額查詢。
返回結果
API 示例
https://api.etherscan.io/api?mole=account&action=txlist&address=&startblock=0&endblock=99999999&page=1&offset=10&sort=asc&apikey=YourApiKeyToken
參數說明
返回結果
API 示例
https://api.etherscan.io/api?mole=account&action=txlistinternal&address=&startblock=0&endblock=2702578&page=1&offset=10&sort=asc&apikey=YourApiKeyToken
參數說明
參數與上一個 API 基本相同,只有 action 是 txlistinternal 這一點不同,這 2 種交易的區別是什麼呢?簡單的理解就是「正常」的交易是會記錄到區塊鏈上的,而「內部」交易是指不會記錄到區塊鏈上的記錄,比如交易失敗的記錄。
另外這個 API 還可以通過交易 hash 查看交易的詳情。
https://api.etherscan.io/api?mole=account&action=txlistinternal&txhash=&apikey=YourApiKeyToken
返回結果
API 示例
參數說明
返回結果
API 示例
參數說明
返回結果
智能合約相關的 API,其實只有一個獲取智能合約介面的 API,但是這個 API 非常有用。
API 示例
參數說明
智能合約的 abi 就是一個 json 對象,通過這個對象我們可以調用其介面方法,後面會寫一篇文章介紹如何操作 abi 對象,敬請期待。
返回結果
返回結果內容比較長,這里省略,就是一個 json 對象,感興趣的可以自行調用該 API 看結果。
賬號和智能合約的 API 已經能滿足大部分的業務需求了,其他模塊的 API 感覺沒什麼太大的作用,這里就不介紹了,感興趣的讀者可以自行查閱。
這里再說下 API 的使用限制,剛才提到每個 API 都有一個 apikey 參數,如果 API 沒加上這個參數的話,每個 API 的請求次數不能超過 5 次每秒。
Etherscan 提供的這些 API 有些是和以太坊提供的 API 有重復的,比如說獲取賬號金額,獲取事件日誌記錄等,但有一些 API 給我們帶來了很大的便利性,比如獲取賬號交易記錄,有了這個 API 就不用使用幾個原生 API 進行各種數據拼接了。
另外 Etherscan 的這套 API 在 Rinkeby 測試網路也有一套一模一樣的,區別只是前面的 url 不同,Rinkeby 的是: api-rinkeby.etherscan.io ,感興趣的同學可以去試試。
❹ Etherscan 的 API使用
雖然以太坊提供了 Web3 和 Json Rpc 這 2 種 API,geth 也額外提供了一些 API ,但是對於開發以太坊應用來說還是顯得有些不足,比如說獲取交易記錄的時間,需要先通過交易的 hash 找到該交易對應的區塊 id,然後才能找到對應的時間,查詢起來相當不方便。
好在 Etherscan 對外提供了一些公共的 API,給我們提供了額外的能力來處理更多的業務場景。
為了方便開發人員更好地使用 ethersacn.io ,網站提供了 一系列 API 供開發人員使用。
API 的使用非常簡單,基本上都是 get 方法,通過 http 請求就可以直接調用,在每個 Api 的說明文檔都有對應的例子可以查看。
API 主要包含以下模塊:賬號、智能合約、交易、區塊、事件日誌、代幣及工具等。
賬號相關的 API,有獲取賬號金額,獲取交易記錄等,該模塊提供的 API 最多。
API 示例
https://api.etherscan.io/api?mole=account&action=balance&address=&tag=latest&apikey=YourApiKeyToken
參數說明
其中 mole、action、apikey 是每個 API 都有的參數,其他的參數則因不同 API 而不同。
返回結果
API 示例
https://api.etherscan.io/api?mole=account&action=balancemulti&address=,,&tag=latest&apikey=YourApiKeyToken
參數說明
(前面有講過的參數就不講了,下同)
與單個賬號金額 API 相比,參數 address 用 , 號分隔多個賬號,最多可支持 20 個賬號的金額查詢。
返回結果
API 示例
https://api.etherscan.io/api?mole=account&action=txlist&address=&startblock=0&endblock=99999999&page=1&offset=10&sort=asc&apikey=YourApiKeyToken
參數說明
返回結果
API 示例
https://api.etherscan.io/api?mole=account&action=txlistinternal&address=&startblock=0&endblock=2702578&page=1&offset=10&sort=asc&apikey=YourApiKeyToken
參數說明
參數與上一個 API 基本相同,只有 action 是 txlistinternal 這一點不同,這 2 種交易的區別是什麼呢?簡單的理解就是「正常」的交易是會記錄到區塊鏈上的,而「內部」交易是指不會記錄到區塊鏈上的記錄,比如交易失敗的記錄。
另外這個 API 還可以通過交易 hash 查看交易的詳情。
https://api.etherscan.io/api?mole=account&action=txlistinternal&txhash=&apikey=YourApiKeyToken
返回結果
API 示例
https://api.etherscan.io/api?mole=account&action=tokentx&contractaddress=&address=&page=1&offset=100&sort=asc&apikey=YourApiKeyToken
參數說明
返回結果
API 示例
https://api.etherscan.io/api?mole=account&action=getminedblocks&address=&blocktype=blocks&page=1&offset=10&apikey=YourApiKeyToken
參數說明
返回結果
智能合約相關的 API,其實只有一個獲取智能合約介面的 API,但是這個 API 非常有用。
API 示例
https://api.etherscan.io/api?mole=contract&action=getabi&address=&apikey=YourApiKeyToken
參數說明
智能合約的 abi 就是一個 json 對象,通過這個對象我們可以調用其介面方法,後面會寫一篇文章介紹如何操作 abi 對象,敬請期待。
返回結果
返回結果內容比較長,這里省略,就是一個 json 對象,感興趣的可以自行調用該 API 看結果。
賬號和智能合約的 API 已經能滿足大部分的業務需求了,其他模塊的 API 感覺沒什麼太大的作用,這里就不介紹了,感興趣的讀者可以自行查閱。
這里再說下 API 的使用限制,剛才提到每個 API 都有一個 apikey 參數,如果 API 沒加上這個參數的話,每個 API 的請求次數不能超過 5 次每秒。
Etherscan 提供的這些 API 有些是和以太坊提供的 API 有重復的,比如說獲取賬號金額,獲取事件日誌記錄等,但有一些 API 給我們帶來了很大的便利性,比如獲取賬號交易記錄,有了這個 API 就不用使用幾個原生 API 進行各種數據拼接了。
另外 Etherscan 的這套 API 在 Rinkeby 測試網路也有一套一模一樣的,區別只是前面的 url 不同,Rinkeby 的是: api-rinkeby.etherscan.io ,感興趣的同學可以去試試。
❺ 以太坊如何使用web3.js或者rpc介面獲取交易數據交易時間與確認數
如果要查詢主網上的交易記錄,可以使用etherscan。但是,如果是你自己搭建的私鏈,應該如何查詢交易記錄呢?
答案是你需要自己監聽鏈上的日誌,存到資料庫里,然後在這個資料庫中查詢。例如:
varaddr=""
varfilter=web3.eth.filter({fromBlock:0,toBlock:'latest',address:addr});
filter.get(function(err,transactions){
transactions.forEach(function(tx){
vartxInfo=web3.eth.getTransaction(tx.transactionHash);
//這時可以將交易信息txInfo存入資料庫
});
});
web3.eth.filter()用來監聽鏈上的日誌,web3.eth.getTransaction()用來提取指定交易的信息,一旦獲得交易信息,就可以存入資料庫供查詢用了。
推薦一個實戰入門,你可以看看:以太坊教程
❻ Quorum介紹
Quorum和以太坊的主要區別:
Quorum 的主要組件:
1,用其自己實現的基於投票機制的共識方式 來代替原來的 「Proof of work」 。
2,在原來無限制的P2P傳輸方式上增加了許可權功能。使得P2P傳輸只能在互相允許的節點間傳輸。
3, 修改區塊校驗邏輯使其能支持 private transaction。
4, Transaction 生成時支持 transaction 內容的替換。這個調整是為了能支持聯盟中的私有交易。
Constellation 模塊的主要職責是支持 private transaction。Constellation 由兩部分組成:Transaction Manager 和 Enclave。Transaction Manager 用來管理和傳遞私有消息,Enclave 用來對私有消息的加解密。
在私有交易中,Transaction Manager 會存儲私有交易的內容,並且會將這條私有交易內容與其他相關的 Transaction Manager 進行交互。同時它也會利用 Enclave 來加密或解密其收到的私有交易。
為了能更有效率的處理消息的加密與解密,Quorum 將這個功能單獨拉出並命名為 Enclave 模塊。Enclave 和 Transaction Manager 是一對一的關系。
在 Quorum 中有兩種交易類型,」Public Transaction」 和 「Privat Transaction」。在實際的交易中,這兩種類型都採用了以太坊的 Transaction 模型,但是又做了部分修改。Quorum 在原有的以太坊 tx 模型基礎上添加了一個新的 「privateFor」 欄位。同時,針對一個 tx 類型的對象添加了一個新的方法 「IsPrivate」。用 「IsPrivate」 方法來判斷 Transaction是 public 還是 private,用 「privateFor」 來記錄 事務只有誰能查看。
Public Transaction 的機理和以太坊一致。Transaction中的交易內容能被鏈上的所有人訪問到。
Private Transaction 雖然被叫做 「Private」,但是在全網上也會出現與其相關的交易。只不過交易的明細只有與此交易有關系的成員才能訪問到。在全網上看到的交易內容是一段hash值,當你是交易的相關人員時,你就能利用這個hash值,然後通過 Transaction Manager 和 Enclave 來獲得這筆交易的正確內容。
Public Transaction的處理流程和以太坊的Transaction流程一致。Transaction 廣播全網後,被礦工打包到區塊中。節點收到區塊並校驗區塊中的 事務 信息。然後根據 Transaction信息更新本地的區塊
Private Transaction也會將 Transaction 廣播至全網。但是它的 Transaction payload已經從原來的真實內容替換為一個hash值。這個hash值是由Transaction Manager提供的。
有兩個共識機制:QuorumChain Consensus 和 Raft-Based Consensus。
在 Quorum 1.2 之前的 Release 版本都採用了 QuorumChain。
從 2.0 版本開始,Quorum 廢棄了 QuorumChain 轉而只支持 Raft-based Consensus。
QuorumChain Consensus 是一個基於投票的共識演算法。其主要特點有:
相比較以太坊的POW,Raft-based 提供了更快更高效的區塊生成方式。相比 QuorumChain,Raft-based 不會產生空的區塊,而且在區塊的生成上比前者更有效率。
要想了解Raft-based Consensus,必須先了解Raft演算法
Raft演算法
Raft是一種一致性演算法,是為了確保容錯性,也就是即使系統中有一兩個伺服器當機,也不會影響其處理過程。這就意味著只要超過半數的大多數伺服器達成一致就可以了,假設有N台伺服器,N/2 +1 就超過半數,代表大多數了。
Raft的工作模式:
raft的工作模式是一個Leader和多個Follower模式,即我們通常說的領導者-追隨者模式。除了這兩種身份,還有Candidate身份。下面是身份的轉化示意圖
1,leader的選舉過程
raft初始狀態時所有server都處於Follower狀態,並且隨機睡眠一段時間,這個時間在0~1000ms之間。最先醒來的server A進入Candidate狀態,Candidate狀態的server A有權利發起投票,向其它所有server發出投票請求,請求其它server給它投票成為Leader。
2,Leader產生數據並同步給Follower
Leader產生數據,並向其它Follower節點發送數據添加請求。其它Follower收到數據添加請求後,判斷該append請求滿足接收條件(接收條件在後面安全保證問題3給出),如果滿足條件就將其添加到本地,並給Leader發送添加成功的response。Leader在收到大多數Follower添加成功的response後。提交後的log日誌就意味著已經被raft系統接受,並能應用到狀態機中了。
Leader具有絕對的數據產生權利,其它Follower上存在數據不全或者與Leader數據不一致的情況時,一切都以Leader上的數據為主,最終所有server上的日誌都會復製成與Leader一致的狀態。
Raft的動態演示: http://thesecretlivesofdata.com/raft/
安全性保證,對於異常情況下Raft如何處理:
1,Leader選舉過程中,如果有兩個FollowerA和B同時醒來並發出投票請求怎麼辦?
在一次選舉過程中,一個Follower只能投一票,這就保證了FollowerA和B不可能同時得到大多數(一半以上)的投票。如果A或者B中其一幸運地得到了大多數投票,就能順利地成為Leader,Raft系統正常運行下去。但是A和B可能剛好都得到一半的投票,兩者都成為不了Leader。這時A和B繼續保持Candidate狀態,並且隨機睡眠一段時間,等待進入到下一個選舉周期。由於所有Follower都是隨機選擇睡眠時間,所以連續出現多個server競選的概率很低。
2,Leader掛了後,如何選舉出新的Leader?
Leader在正常運行時候,會周期性的向Follower節點發送數據的同步請求,同時也是起到一個心跳作用。Follower節點如果在一段時間之內(一般是2000ms左右)沒有收到數據同步請求,則認為Leader已經死了,於是進入到Candidate狀態,開始發起投票競選新的Leader,每個新的Leader產生後就是一個新的任期,每個任期都對應一個唯一的任期號term。這個term是單調遞增的,用來唯一標識一個Leader的任期。投票開始時,Candidate將自己的term加1,並在投票請求中帶上term;Follower只會接受任期號term比自己大的request_vote請求,並為之投票。 這條規則保證了只有最新的Candidate才有可能成為Leader。
3,Follower的數據的生效時間
Follower在收到一條添加數據請求後,是否立即保存並將其應用到狀態機中去?如果不是立即應用,那麼由什麼來決定該條日誌生效的時間?
首先會檢查這條數據同步請求的來源信息是否與本地保存的leader信息符合,包括leaderId和任期號term。檢查合法後就將日誌保存到本地中,並給Leader回復添加log成功,但是不會立即將其應用到本地狀態機。Leader收到大部分Follower添加log成功的回復後,就正式將這條日誌commit提交。Leader在隨後發出的心跳append_entires中會帶上已經提交日誌索引。Follower收到Leader發出的心跳append_entries後,就可以確認剛才的log已經被commit(提交)了,這個時候Follower才會把日誌應用到本地狀態機。下表即是append_entries請求的內容,其中leaderCommit即是Leader已經確認提交的最大日誌索引。Follower在收到Leader發出的append_entries後即可以通過leaderCommit欄位決定哪些日誌可以應用到狀態機。
4,向raft系統中添加新機器時,由於配置信息不可能在各個系統上同時達到同步狀態,總會有某些server先得到新機器的信息,有些server後得到新機器的信息。比如在raft系統中有三個server,在某個時間段中新增加了server4和server5這兩台機器。只有server3率先感知到了這兩台機器的添加。這個時候如果進行選舉,就有可能出現兩個Leader選舉成功。因為server3認為有3台server給它投了票,它就是Leader,而server1認為只要有2台server給它投票就是Leader了。raft怎麼解決這個問題呢?
產生這個問題的根本原因是,raft系統中有一部分機器使用了舊的配置,如server1和server2,有一部分使用新的配置,如server3。解決這個問題的方法是添加一個中間配置(Cold, Cnew),這個中間配置的內容是舊的配置表Cold和新的配置Cnew。這個時候server3收到添加機器的消息後,不是直接使用新的配置Cnew,而是使用(Cold, Cnew)來做決策。比如說server3在競選Leader的時候,不僅需要得到Cold中的大部分投票,還要得到Cnew中的大部分投票才能成為Leader。這樣就保證了server1和server2在使用Cold配置的情況下,還是只可能產生一個Leader。當所有server都獲得了添加機器的消息後,再統一切換到Cnew。raft實現中,將Cold,(Cold,Cnew)以及Cnew都當成一條普通的日誌。配置更改信息發送Leader後,由Leader先添加一條 (Cold, Cnew)日誌,並同步給其它Follower。當這條日誌(Cold, Cnew)提交後,再添加一條Cnew日誌同步給其它Follower,通過Cnew日誌將所有Follower的配置切換到最新。
Raft演算法和以太坊結合
所以為了連接以太坊節點和 Raft 共識,Quorum 採用了網路節點和 Raft 節點一對一的方式來實現 Raft-based 共識
一個Transaction完整流程
1,客戶端發起一筆 Transaction並通過 RPC 來呼叫節點。
2,節點通過以太坊的 P2P 協議將節點廣播給網路。
3,當前的 Raft leader 對應的以太坊節點收到了 Transaction後將它打包成區塊。
區塊被 編碼後傳遞給對應的 Raft leader。
leader 收到區塊後通過 Raft 演算法將區塊傳遞給 follower。這包括如下步驟:
3.1,leader 發送 AppendEntries 指令給 follower。
3.2,follower 收到這個包含區塊信息的指令後,返回確認回執給 leader。
3.3,leader 收到不少於指定數量的確認回執後,發送確認 append 的指令給 follower。
3.4,follower 收到確認 append 的指令後將區塊信息記錄到本地的 Raft log 上。
3.5,Raft 節點將區塊傳遞給對應的 Quorum 節點。Quorum 節點校驗區塊的合法性,如果合法則記錄到本地鏈上。
參考鏈接: http://blog.csdn.net/about_blockchain/article/details/78684901
❼ 以太國際空間誰知道怎麼玩。EIS幣怎麼交易
現在我們大家都很關注關於以太坊方面的問題,那麼關於以太幣怎麼交易?我想我們大家應該會很想了解一些內容,那麼下面就讓我們小編在這里就來為大家好好的介紹一下很多內容關於以太幣怎麼交易?以太坊的交易最直觀解釋:從外部賬戶發送到區塊鏈上的另一個賬戶的消息和簽名的數據包。
包含如下內容:
發送者的簽名
接收的地址
轉移的數字貨幣數量等內容
以太坊上的交易都是需要支付費用,和比特幣以比特幣來支付一定的交易費用不同,以太坊上固定了這個環節,那麼這個間接理解是以太坊的一種安全防範錯誤,防止了大量的無意義的交易,保證一定的安全性,特別是智能合約的創建、執行、調用都需要消耗費用,那麼也保證了整個系統的穩定性,防止了一些鏈上無意義的惡意行為。
交易手續費
以太坊的核心是EVM,以太坊虛擬機,那麼在EVM中執行的位元組碼都是要支付費用。也就是經常看到的Gas、Gas limit、Gas Price這幾個概念。
Gas:字面理解就是汽油,以太坊和日常的汽車一樣需要Gas才能運行。Gas是一筆交易過程中計算消耗的基本單位。有一個列表可以直觀看到在以太坊中操作的Gas消耗量:
操作Gas消耗具體內容
step1執行周期的默認費用。
stop0終止操作是免費的。
suicide0智能合約賬戶的內部數據存儲空間,當合約賬戶調用suicide()方法時,該值將被置為null。
sha320加解密
sload20在固定的存儲器中去獲取
sstore100輸入到固定的存儲器中
balance20賬戶余額
create100創建合約
call20初始化一個只讀調用
memory1擴充內存額外支付的費用
txdata5交易過程中數據或者編碼的每一個位元組的消耗
transaction500交易費用
contract creation53000homestead中目前從21000調整到53000
所以有些公司或者個人覺得區塊鏈技術去中介化,不需要中心伺服器,這種開發模式是比較便宜的,但是事實上區塊鏈的開發不比之前的那些傳統軟體開發來的便宜。
Gas Price:字面理解汽油價格,這個就像你去加油站,95#汽油今天是什麼價格。一個Gas Price就是單價,那麼你的交易費用=Gas*Gas Price,然後以以太幣來ether來支出。當然你覺得我不想支付費用,你可以設置Gas Price為0,但是選擇權在礦工手中,礦工有權選擇收納交易和收取費用,那麼最簡單的想想很難讓一個礦工去接收一個價格很低的交易吧。另外提一句,以太坊默認的Gas Price是1wei。
Gas Limit:字面理解就是Gas的限制,限制是必要的,沒有限制就沒有約束。這個Gas Limit是有兩個意思的。首先針對單個交易,那麼這個表示交易的發起者他願意支付最多是多少Gas,這個交易發起者在發起交易的時候需要設置好。還有一個是針對區塊的Gas Limit,一個單獨的區塊也有Gas的限制。
假設幾個場景來說明Gas的使用:
用戶設置Gas Limit,那麼在交易過程中,如果你的實際消耗的Gas used
用戶設置Gas Limit,那麼交易過程中,如果你的實際消耗的Gas used > Gas Limit,那麼礦工肯定發現你的Gas不足,這個交易就無法執行完成,這個之後會回滾到執行之前的狀態,這個時候礦工會收取Gas Price*Gas Limit。
區塊的Gas Limit,區塊中有一個Gas上限,收納的交易會出現不同的用戶指定的Gas Limit。那麼礦工就會根據區塊限制的Gas Limit來選擇,「合理」選擇打包交易。
具體交易
以太坊上交易可以是簡單的以太幣的轉移,同時也可以是智能合約的代碼消息。列個表格看下交易的具體內容:
代碼內容
from交易發起者的地址、不能為空,源頭都沒有不合理。
to交易接收者的地址(這個可以為空,空的時候就表示是一個合約的創建)
value轉移的以太幣數量
data數據欄位。這個欄位存在的時候表示的是,交易是一個創建或者是一個調用智能合約的交易
Gas Limit字面理解就是Gas的限制,限制是必要的,沒有限制就沒有約束。這個Gas Limit是有兩個意思的。首先針對單個交易,那麼這個表示交易的發起者他願意支付最多是多少Gas,這個交易發起者在發起交易的時候需要設置好。還有一個是針對區塊的Gas Limit,一個單獨的區塊也有Gas的限制。
Gas Price一個Gas Price就是單價,那麼你的交易費用=Gas*Gas Price,然後以以太幣來ether來支出。以太坊默認的Gas Price是1wei。
nonce用於區別用戶發出交易的標識。
hash交易ID,是由上述的信息生成的一個hash值
r、s、v交易簽名的三部分,交易發起者的私鑰對hash簽名生成。
交易分三種類型
轉賬:簡單明了的以太坊上的以太幣的轉移,就和比特幣類似,A向B轉移一定數量的以太幣。這種交易包含:交易發起者、接收者、value的數量,其餘類似Gas Limit、hash、nonce都會默認生成。所以你會看到一段代碼:
web3.eth.sendTransaction({ from: "交易發起者地址", to:「交易接收者地址」, value: 數量});
智能合約創建:創建智能合約就是把智能合約部署到區塊鏈上,那麼這個時候to是一個空的欄位。data欄位則是初始化合約的代碼。所以看到代碼:
web3.eth.sendTransaction({ from: "交易發起者地址", data: "contract binary code"});
智能合約執行:合約創建部署在區塊鏈上,那麼執行就是會加上to欄位到要智能合約執行的地址,然後data欄位來指定調用的方法和參數的傳遞,所以看到代碼:
web3.eth.sendTransaction({ from: "交易發起者地址", to:「合約執行者地址」, data:「調用的方法和參數的傳遞」});
以上大致就是交易的類型。
交易的確認
和比特幣一樣,以太坊的交易需要後續區塊確認後,節點同步後、才能確認。簡單理解就是多挖出一些區塊來,通過驗證後這一筆交易才算確認,以太坊時常會出現擁堵的情況,所以有時候需要等待確認。
轉賬、合約交易流轉
首先交易發起者A發起一筆轉賬交易,那麼發送的格式如下:
代碼具體內容
from交易發起者的地址
to交易接收者的地址
value轉移的以太幣數量
GasGas的量
Gas PriceGas的單價
data發送給接收者的消息
nonce交易編號
節點驗證:以太坊網路中會有節點收到A發送出來的消息,那麼會去檢查這個消息格式時候有效,然後計算Gas Limit。這個時候回去驗證A的以太坊余額,如果余額不足,那麼就返回錯誤,不予處理。一旦A發送的消息通過了節點的驗證,那麼節點就會把這個交易放到交易存儲池中。並廣播到區塊鏈網路。
礦工驗證:那麼寫入區塊鏈必須要礦工打包,礦工在接收到A發出的交易,會和其他交易一塊打包,普通轉賬交易打包即可,那麼合約調用的交易則需要在礦工本地的EVM上去執行調用的合約代碼,代碼執行過程中檢查Gas的消耗。一旦Gas消耗完了,那麼就回滾,如果Gas足夠那麼返回多餘的Gas。並廣播到區塊鏈網路。
其餘節點:重復節點驗證步驟,然後合約也會在本地EVM上執行驗證。通過驗證後同步區塊鏈。
首先還是發起者A發起一個創建智能合約的交易請求。格式如下:
代碼具體內容
from交易發起者的地址
to0
value轉移的以太幣數量
GasGas的量
Gas PriceGas的單價
data合約代碼
nonce交易編號
節點驗證:
以太坊網路中會有節點收到A發送出來的消息,檢查交易是否有效,格式是否正確,驗證交易簽名。計算Gas,確定下發起者的地址,然後查詢A賬戶以太幣的余額。如果余額不足,那麼就返回錯誤,不予處理。一旦A發送的消息通過了節點的驗證,那麼節點就會把這個交易放到交易存儲池中。並廣播到區塊鏈網路。
礦工驗證:
礦工將交易打包,那麼會根據交易費用和合約代碼,來創建合約賬戶,在賬戶的空間中部署合約。這里說下合約地址(智能合約賬戶的地址是有發起者的地址和交易的隨機數作為輸入,然後通過加密演算法生成)。交易確認後會把智能合約的地址返回給A。且廣播到區塊鏈網路。
其餘節點:
重復節點驗證步驟,驗證區塊,在節點的內存池中更新A的智能合約交易,同步區塊鏈,且智能合約部署在自己本地的區塊鏈中。