前面已經完成FISCO BCOS 相關底層搭建、sdk使用、控制檯、WeBASE中間件平臺等系列實戰開發,
本次進行最後一個部分,體系化管理區塊鏈底層,創建有序的底層控管制度,實現權限化管理。html
完成:鏈管理、系統管理、數據上鍊操做等。java
其中數據上鍊分爲:合約版本上鍊、crudService 版本上鍊等操做。git
在進行以前,咱們首先要了解一下,fisco bcos 的底層權限系統介紹。github
https://mp.weixin.qq.com/s/QJNk71w4o_cGX2O-1aW29Qweb
一、底層默認是能夠部署合約,只有一旦操做 grantDeployAndCreateManager 命令,纔開始限制用戶部署合約權限spring
ps:一開始權限基本開放,而不是像常規系統設計那樣,一開始權限爲無,等到分配好權限才能夠相應的的操做。sql
二、底層默認是寫表操做,寫表操做就有了CRUD等操做,常規的區塊鏈體系是在不斷區塊打包過程當中附加數據,FISCO BCOS 提供寫表操做,實質上業務數據能夠有修改的權限,數據庫
因此在鏈搭建好後,就必須限制Update等操做權限,而且在業務設計時候,須要多方去驗證修改數據等過程,才能夠防止區塊鏈底層數據讓高權限的人的篡改。ubuntu
ps:與官方人員交談,提供的例子api
好比官方給出的存證的例子,一個證據X,須要A,B機構確認。先是證據X上鍊(一筆交易),而後機構A看到證據,
確認有效(又一筆交易),機構B演的證據,確認有效(又一筆交易)。三筆交易完成業務共識的邏輯。
別人取證X的時候,讀區塊鏈,查看是否A,B都確認過,確認過了,證據X纔有效。
咱們在底層完成各類系統化的搭建,如今要使用多種方式進行權限管控,以及數據上鍊等操做。
一、咱們首先要創建鏈管理員、系統管理員、普通用戶。
二、其次咱們要使用控制檯 或sdk進行管理員等設定。
三、對合約的部署權限、以及數據權限更新操做作受權。
四、在sdk 中配置受權用戶的pem、p12密鑰的使用。
五、使用合約操做,進行合約部署,合約CRUD操做。
六、使用CRUDService 進行數據操做。
七、使用PermissionService 進行權限控制。
最後根據咱們設定好的權限,完成多個不一樣身份用戶進行的數據操做,這樣咱們就完成生產環境下的數據上鍊操做。
備註:如下操做,能夠參考web3sdk單元測試。官方github web3sdk 地址:https://github.com/FISCO-BCOS/web3sdk
建立用戶,用於後續的管理員設置,進行權限管理設置。
官方資料:https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/tutorial/account.html
FISCO BCOS 底層 支持控制檯建立帳戶、sdk 建立帳戶
先採用控制檯進行基礎用戶建立,以及基本全是設置
在console 目錄下 使用bash get_account.sh、bash get_account.sh -p 建立不一樣的帳戶 Usage: ./get_account.sh default generate account and store private key in PEM format file(默認生成pem格式用戶) -p generate account and store private key in PKCS12 format file(默認生成p12格式用戶) -k [FILE] calculate address of PEM format [FILE](經過pem 私鑰文件生成帳戶地址) -P [FILE] calculate address of PKCS12 format [FILE](經過p12 私鑰文件生成帳戶地址) -h Help
ubuntu@VM-16-14-ubuntu:~/generator/console$ bash get_account.sh [INFO] Account Address : 0x83a37766067ea59eea78135b20a4afc251246e88 [INFO] Private Key (pem) : accounts/0x83a37766067ea59eea78135b20a4afc251246e88.pem
一、具備 發佈合約權限的用戶
ubuntu@VM-16-14-ubuntu:~/generator/console$ bash get_account.sh -p Enter Export Password:123456 Verifying - Enter Export Password:123456 [INFO] Account Address : 0xb93bb9276d97f5f75ea574965beab99f72310e45 [INFO] Private Key (p12) : accounts/0xb93bb9276d97f5f75ea574965beab99f72310e45.p12
二、系統管理員
ubuntu@VM-16-14-ubuntu:~/generator/console$ bash get_account.sh -p Enter Export Password: Verifying - Enter Export Password: [INFO] Account Address : 0xca96eb0e7c70c9117a2b5bda65cbcfc1b37a35c2 [INFO] Private Key (p12) : accounts/0xca96eb0e7c70c9117a2b5bda65cbcfc1b37a35c2.p12
三、普通用戶
ubuntu@VM-16-14-ubuntu:~/generator/console$ bash get_account.sh -p Enter Export Password: Verifying - Enter Export Password: [INFO] Account Address : 0x190b5d0a7ed4754c9226ee96c50cd125ec5720bf [INFO] Private Key (p12) : accounts/0x190b5d0a7ed4754c9226ee96c50cd125ec5720bf.p12
pem登陸方式:
bash ./start.sh 1 -pem accounts/0x83a37766067ea59eea78135b20a4afc251246e88.pem
p12 登陸方式:(須要輸入密碼)
bash ./start.sh 1 -p12 accounts/0xb93bb9276d97f5f75ea574965beab99f72310e45.p12
設定帳戶1爲鏈管理員帳戶,帳戶2爲系統管理員帳戶,帳戶3爲普通帳戶。
一、鏈管理員帳戶擁有權限管理的權限,即能分配權限。
[group:1]> grantDeployAndCreateManager 0x83a37766067ea59eea78135b20a4afc251246e88 { "code":0, "msg":"success" }
二、系統管理員帳戶能夠管理系統相關功能的權限,每一種系統功能權限都須要單獨分配,
具體包括部署合約和建立用戶表的權限、管理節點的權限、利用CNS部署合約的權限以及修改系統參數的權限。
鏈管理員帳戶能夠受權其餘帳戶爲鏈管理員帳戶或系統管理員帳戶,
[group:1]> grantDeployAndCreateManager 0xb93bb9276d97f5f75ea574965beab99f72310e45 { "code":0, "msg":"success" }
三、也能夠受權指定帳號能夠寫指定的用戶表,即普通帳戶。
用某個用戶登陸後,使用命令賦予權限,前提是他擁有該權限操做
applicationContext.xml 文件配置修改,其中包括密鑰文件的配置。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="encryptType" class="org.fisco.bcos.web3j.crypto.EncryptType"> <constructor-arg value="0"/> <!-- 0:standard 1:guomi --> </bean> <bean id="groupChannelConnectionsConfig" class="org.fisco.bcos.channel.handler.GroupChannelConnectionsConfig"> <property name="allChannelConnections"> <list> <!-- 每一個羣組須要配置一個bean,每一個羣組能夠配置多個節點 --> <bean id="group1" class="org.fisco.bcos.channel.handler.ChannelConnections"> <property name="groupId" value="1" /> <!-- 羣組的groupID --> <property name="connectionsStr"> <list> <value>對應的節點ip:20201</value> <value>對接節點ip:20200</value> <!-- IP:channel_port --> </list> </property> </bean> <bean id="group2" class="org.fisco.bcos.channel.handler.ChannelConnections"> <property name="groupId" value="2" /> <!-- 羣組的groupID --> <property name="connectionsStr"> <list> <value>127.0.0.1:20202</value> <value>127.0.0.1:20203</value> </list> </property> </bean> </list> </property> </bean>
<bean id="channelService" class="org.fisco.bcos.channel.client.Service" depends-on="groupChannelConnectionsConfig"> <property name="groupId" value="1" /> <!-- 配置鏈接羣組1 --> <property name="agencyName" value="fisco" /> <!-- 配置機構名 --> <property name="allChannelConnections" ref="groupChannelConnectionsConfig"></property> </bean> <bean id="p12" class="org.fisco.bcos.channel.client.P12Manager" init-method="load" > <property name="password" value="123456" /> <property name="p12File" value="classpath:0xb93bb9276d97f5f75ea574965beab99f72310e45.p12" /> </bean> <bean id="pem" class="org.fisco.bcos.channel.client.PEMManager" init-method="load" > <property name="pemFile" value="classpath:0x83a37766067ea59eea78135b20a4afc251246e88.pem" /> </bean> </beans>
若是要寫單元測試
也要把相關配置copy 過去,詳情見圖
一、基礎設置,包括具備部署合約權限用戶設置
private Credentials credentials; private static BigInteger gasPrice = new BigInteger("300000000"); private static BigInteger gasLimit = new BigInteger("300000000"); @Autowired Web3j web3j; protected String tempDirPath = new File("src/main/resources/").getAbsolutePath(); //這很重要,沒有這個沒法經過 @Before public void setUp() throws Exception { ApplicationContext context = new ClassPathXmlApplicationContext( "classpath:applicationContext-keystore-sample.xml"); // test p12 P12Manager p12 = context.getBean(P12Manager.class); ECKeyPair p12KeyPair = p12.getECKeyPair(); System.out.println("p12KeyPair.getPrivateKey() = " + p12KeyPair.getPrivateKey().toString(16)); System.out.println("p12KeyPair.getPublicKey() = " + p12KeyPair.getPublicKey().toString(16)); ECPublicKey publicKey = (ECPublicKey) p12.getPublicKey(); byte[] publicKeyBytes = publicKey.getQ().getEncoded(false); BigInteger publicKeyValue = new BigInteger(1, Arrays.copyOfRange(publicKeyBytes, 1, publicKeyBytes.length)); System.out.println("publicKeyValue = " + publicKeyValue.toString(16)); credentials = Credentials.create(p12KeyPair);//這裏將具備合約部署權限的用戶設置進去,當前操做對象 System.out.println("credentials getAddress= " + credentials.getAddress()); } @After public void tearDown() { }
二、部署合約
@Test //一、部署合約 public void DeployTable() throws Exception { // 部署合約 TableTemp tableTemp = TableTemp.deploy(web3j, credentials, new StaticGasProvider(gasPrice, gasLimit)).send(); if (tableTemp != null) { System.out.println("TableTemp address is: " + tableTemp.getContractAddress()); } }
三、建立表合約操做,此時,須要用到部署合約時候生成的地址
//二、建立表操做 @Test public void CreateTableTest()throws Exception { String contractAddress = "0xb4245b7b6cc33f8f65d8bf37f084dec3e31ca573";//合約部署時候的生成的地址 // 加載合約地址 TableTemp tableTemp = TableTemp.load(contractAddress, web3j, credentials, new StaticGasProvider(gasPrice, gasLimit)); TransactionReceipt receipt = tableTemp.create().send(); System.out.println("AssetTest.AssetTransfer receipt="+receipt.toString()); }
四、插入表操做(合約地址改成本身測試的,筆者因爲屢次單元測試,合約地址不一樣)
//3.一、插入表操做 無返回值操做 @Test public void InsertTableTest()throws Exception { String contractAddress = "0x215ac9f7af5766ff45d80082091856b54fcf4308"; // 加載合約地址 TableTemp tableTemp = TableTemp.load(contractAddress, web3j, credentials, new StaticGasProvider(gasPrice, gasLimit)); String name = "wq"; int item_id = Integer.parseInt("2"); String item_name ="aaa"; String item_address ="ddd"; tableTemp.insert(name, BigInteger.valueOf(item_id), item_name,item_address).send(); } //3.二、插入表操做 @Test public void InsertTableByReturnTest()throws Exception { String contractAddress = "0xb4245b7b6cc33f8f65d8bf37f084dec3e31ca573"; // 加載合約地址 TableTemp tableTemp = TableTemp.load(contractAddress, web3j, credentials, new StaticGasProvider(gasPrice, gasLimit)); String name = "ak"; int item_id = Integer.parseInt("1"); String item_name ="tempUser"; String item_address ="北京"; TransactionReceipt send = tableTemp.insert(name, BigInteger.valueOf(item_id), item_name, item_address).send(); System.out.println(" send= "+send.toString()); }
五、刪除表操做
//4.1刪除表數據操做 @Test public void DeleteTableTest()throws Exception { String contractAddress = "0x215ac9f7af5766ff45d80082091856b54fcf4308"; // 加載合約地址 TableTemp tableTemp = TableTemp.load(contractAddress, web3j, credentials, new StaticGasProvider(gasPrice, gasLimit)); TransactionReceipt send= tableTemp.remove("ak",BigInteger.valueOf(1)).send(); System.out.println("send.toString() = " + send.toString()); System.out.println("send.getContractAddress() = " + send.getContractAddress()); System.out.println("send.getBlockHash() = " + send.getBlockHash()); System.out.println("send.getBlockNumber() = " + send.getBlockNumber()); } //4.2刪除表數據操做 @Test public void DeleteTableByReturnTest()throws Exception { String contractAddress = "0xb4245b7b6cc33f8f65d8bf37f084dec3e31ca573"; // 加載合約地址 TableTemp tableTemp = TableTemp.load(contractAddress, web3j, credentials, new StaticGasProvider(gasPrice, gasLimit)); int item_id = Integer.parseInt("1"); String name="ak"; RemoteCall<TransactionReceipt> remove = (RemoteCall<TransactionReceipt>) tableTemp.remove(name,BigInteger.valueOf(item_id)); TransactionReceipt transactionReceipt = remove.send(); List<TableTemp.RemoveResultEventResponse> removeResultEvents = tableTemp.getRemoveResultEvents(transactionReceipt); if (removeResultEvents.size() > 0) { TableTemp.RemoveResultEventResponse reomveResultEventResponse = removeResultEvents.get(0); System.out.println( "removeCount = " + reomveResultEventResponse.count.intValue()); } else { System.out.println("tableTemp table does not exist."); } }
六、查詢表操做,因爲合約返回字段有限,最好不要超過三個,有可能會報錯。若是使用返回strust是能夠解決該問題的。
開頭加上這個:pragma experimental ABIEncoderV2;
返回值能夠用struct
//五、表查詢 @Test public void SelectTableTest() throws Exception{ String contractAddress = "0xa94c07af700bf2e435a3051b0a98f2f75eca0298"; // 加載合約地址 TableTemp tableTemp = TableTemp.load(contractAddress, web3j, credentials, new StaticGasProvider(gasPrice, gasLimit)); Tuple3<List<byte[]>, List<BigInteger>, List<byte[]>> lists = tableTemp.select("ak").send(); //這個只是返回合約執行的結果,不會返回自己數據庫表數據 // System.out.println("send.toString() = " + send.toString()); List<byte[]> value1 = lists.getValue1(); List<BigInteger> value2 = lists.getValue2(); List<byte[]> value3 = lists.getValue3(); for (int i = 0; i < value1.size(); i++) { String name = new String(value1.get(i)); System.out.println("name = " + name); int item_id = value2.get(i).intValue(); System.out.println("item_id = " + item_id); String item_name = new String(value3.get(i)); System.out.println("item_name = " + item_name); } }
七、更新表操做,當前筆者還沒設置更新操做權限,因此該方法是能夠修改表數據
//六、表更新 @Test public void UpateTableTest() throws Exception{ String contractAddress = "0xb940c1966a6ce94484f0fdabd3bb8cb38edc9dfd"; // 加載合約地址 TableTemp tableTemp = TableTemp.load(contractAddress, web3j, credentials, new StaticGasProvider(gasPrice, gasLimit)); TransactionReceipt ak= tableTemp.update("ak",BigInteger.valueOf(1),"121","wew").send(); System.out.println("ak.toString() = " + ak.toString()); }
ps:因爲合約操做在實際中返回值等問題,可能存在許多不肯定等坑,因此和官方聊以後,可使用crudService進行表的操做。
CrudService 自己就是對錶的操做的服務封裝。
這裏的單元測試須要用到 基礎設置TestBase,主要配置具備表操做權限的用戶。
package customTest; import java.math.BigInteger; import java.util.Arrays; import org.bouncycastle.jce.interfaces.ECPublicKey; import org.fisco.bcos.channel.client.P12Manager; import org.fisco.bcos.channel.client.Service; import org.fisco.bcos.web3j.crypto.Credentials; import org.fisco.bcos.web3j.crypto.ECKeyPair; import org.fisco.bcos.web3j.protocol.Web3j; import org.fisco.bcos.web3j.protocol.channel.ChannelEthereumService; import org.fisco.bcos.web3j.tx.gas.StaticGasProvider; import org.junit.AfterClass; import org.junit.BeforeClass; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestBase { public static ApplicationContext context = null; public static Credentials credentials; protected static Web3j web3j; protected static BigInteger gasPrice = new BigInteger("30000000"); protected static BigInteger gasLimit = new BigInteger("30000000"); protected static String address; protected static BigInteger blockNumber; protected static String blockHash; protected static String txHash; @BeforeClass public static void setUpBeforeClass() throws Exception { context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml"); Service service = context.getBean(Service.class); service.run(); ChannelEthereumService channelEthereumService = new ChannelEthereumService(); channelEthereumService.setChannelService(service); web3j = Web3j.build(channelEthereumService, service.getGroupId()); ApplicationContext context = new ClassPathXmlApplicationContext( "classpath:applicationContext-keystore-sample.xml"); // test p12 P12Manager p12 = context.getBean(P12Manager.class); ECKeyPair p12KeyPair = p12.getECKeyPair(); System.out.println("p12KeyPair.getPrivateKey() = " + p12KeyPair.getPrivateKey().toString(16)); System.out.println("p12KeyPair.getPublicKey() = " + p12KeyPair.getPublicKey().toString(16)); ECPublicKey publicKey = (ECPublicKey) p12.getPublicKey(); byte[] publicKeyBytes = publicKey.getQ().getEncoded(false); BigInteger publicKeyValue = new BigInteger(1, Arrays.copyOfRange(publicKeyBytes, 1, publicKeyBytes.length)); System.out.println("publicKeyValue = " + publicKeyValue.toString(16)); credentials = Credentials.create(p12KeyPair); System.out.println("credentials getAddress= " + credentials.getAddress()); } @AfterClass public static void setUpAfterClass() throws Exception { ((ClassPathXmlApplicationContext) context).destroy(); } }
如下是crudservice 的單元測試全過程操做,依法操做就能夠了,關鍵地方已經有了註釋。
package customTest; import org.bouncycastle.jce.interfaces.ECPublicKey; import org.fisco.bcos.Application; import org.fisco.bcos.channel.client.P12Manager; import org.fisco.bcos.temp.TableTemp; import org.fisco.bcos.web3j.crypto.Credentials; import org.fisco.bcos.web3j.crypto.ECKeyPair; import org.fisco.bcos.web3j.precompile.crud.CRUDService; import org.fisco.bcos.web3j.precompile.crud.Condition; import org.fisco.bcos.web3j.precompile.crud.Entry; import org.fisco.bcos.web3j.precompile.crud.Table; import org.fisco.bcos.web3j.protocol.Web3j; import org.fisco.bcos.web3j.tx.gas.StaticGasProvider; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.test.context.junit4.SpringRunner; import java.io.File; import java.math.BigInteger; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Random; import static org.junit.jupiter.api.Assertions.assertEquals; /* * 一、繼承 TestBase,配置文件在main的java的resources中applicationContext.xml * */ @RunWith(SpringRunner.class) @SpringBootTest(classes = Application.class) public class CRUDServiceTest extends TestBase{ //這裏若是設置了權限,那麼必須權限用戶纔可使用,請看TestBase 中的改造,credentials private CRUDService crudSerivce = new CRUDService(web3j, credentials); @SuppressWarnings("unchecked") @Test public void CreateTest() throws Exception { String tableName = "t_item2"; String key = "name"; String valueFields = "item_id, item_name,item_address,item_count"; Table table = new Table(tableName, key, valueFields); // create table int resultCreate = crudSerivce.createTable(table); Assert.assertEquals(resultCreate, 0); } @SuppressWarnings("unchecked") @Test public void Insert()throws Exception{ String tableName = "t_item2"; String key = "name"; Table table = new Table(tableName, key); int insertResult = 0; int num = 5; for(int i = 1; i <= num; i++) { Entry insertEntry = table.getEntry(); insertEntry.put("item_id", "q"); insertEntry.put("item_name", "q"+i); insertEntry.put("item_address", "q"+i); insertEntry.put( "item_count",BigInteger.valueOf(i).toString()); table.setKey("q"); insertResult += crudSerivce.insert(table, insertEntry); } Assert.assertEquals(insertResult, num); } @SuppressWarnings("unchecked") @Test public void Select()throws Exception{ String tableName = "t_item2"; String key = "name"; Table table = new Table(tableName, key); // select records Condition condition1 = table.getCondition(); condition1.EQ("name", "q"); condition1.EQ("item_id", "q"); // condition1.Limit(1); table.setKey("q");//查詢記錄sql語句必須在where子句中提供表的主鍵字段值。 List<Map<String, String>> resultSelect1 = crudSerivce.select(table, condition1); Assert.assertEquals(resultSelect1.get(0).get("name"), "q"); Assert.assertEquals(resultSelect1.get(0).get("item_id"), "q"); Assert.assertEquals(resultSelect1.get(0).get("item_name"), "q1"); } @SuppressWarnings("unchecked") @Test public void Update() throws Exception{ String tableName = "t_item2"; String key = "name"; Table table = new Table(tableName, key); int num = 5; table.setKey("q");//查詢記錄sql語句必須在where子句中提供表的主鍵字段值。 Entry updateEntry = table.getEntry(); updateEntry.put("item_id", "徐徐吹v下次v"); updateEntry.put("item_name", "121212"); Condition updateCondition = table.getCondition(); updateCondition.EQ("name", "q"); updateCondition.EQ("item_id", "aaaaa"); int updateResult = crudSerivce.update(table, updateEntry, updateCondition); Assert.assertEquals(updateResult, num); } }
ps:上述操做除了建立表有權限用戶須要操做,其餘的操做任意用戶都可以操做。
本例子,就是經過第一次建立表操做,無受權和有受權等模式屢次測試,從而進行驗證當咱們設置表更新權限後,沒有表更新權限的用戶是沒法進行更新表操做的,賦予這個用戶更新表操做的權限後,就能夠進行表更新操做。
package customTest; import org.fisco.bcos.channel.client.PEMManager; import org.fisco.bcos.temp.TableTemp; import org.fisco.bcos.web3j.crypto.Credentials; import org.fisco.bcos.web3j.crypto.ECKeyPair; import org.fisco.bcos.web3j.precompile.crud.CRUDService; import org.fisco.bcos.web3j.precompile.crud.Condition; import org.fisco.bcos.web3j.precompile.crud.Entry; import org.fisco.bcos.web3j.precompile.crud.Table; import org.fisco.bcos.web3j.precompile.permission.PermissionService; import org.fisco.bcos.web3j.tx.gas.StaticGasProvider; import org.junit.Assert; import org.junit.Test; import static org.junit.Assert.assertEquals; public class PermissionTest extends TestBase { @Test // 受權新建立用戶的權限,測試它部署合約的權限,正常不受權沒法部署 public void PermissionDeploy() throws Exception { //一、初始化建立一個用戶,沒有在底層註冊過的 String tempAddress="0x80e3c3f1f1140fbc550fbfdaa318073af373141d"; String tempPriKey="9265efb6b860ef244f4fbe3dd445f7829e86d11226573190c026323f77ebcd22"; String tempPublicKey="1f9c09a4df7e336961c06e1f2373fb2ef6a1b642c444652a7a5a84b04bdc668431bbddab4a1665cb382d6a94aee9ff18bf88210bae7a2388315b2bc5253bcaa"; //pem 鏈管理員進行操做,對新用戶進行合約部署權限受權 PEMManager pem = context.getBean(PEMManager.class); ECKeyPair pemKeyPair = pem.getECKeyPair(); //一、鏈管理員操做 受權新用戶的能夠發佈和部署合約 credentials = Credentials.create(pemKeyPair); PermissionService permissionService = new PermissionService(web3j, credentials); String s = permissionService.grantDeployAndCreateManager(tempAddress); System.out.println("s = " + s);//這個是受權狀態 //二、使用新用戶新合約部署測試 Credentials userCredentials=Credentials.create(tempPriKey,tempPublicKey); // 部署合約 TableTemp tableTemp = TableTemp.deploy(web3j, userCredentials, new StaticGasProvider(gasPrice, gasLimit)).send(); if (tableTemp != null) { System.out.println("TableTemp address is: " + tableTemp.getContractAddress()); } } @Test // 受權新建立用戶的權限,用戶表操做修改權限 public void PermissionGrantUserTable() throws Exception { //一、初始化建立一個用戶,沒有在底層註冊過的 String tempAddress="0x80e3c3f1f1140fbc550fbfdaa318073af373141d"; String tempPriKey="9265efb6b860ef244f4fbe3dd445f7829e86d11226573190c026323f77ebcd22"; String tempPublicKey="1f9c09a4df7e336961c06e1f2373fb2ef6a1b642c444652a7a5a84b04bdc668431bbddab4a1665cb382d6a94aee9ff18bf88210bae7a2388315b2bc5253bcaa"; //pem 鏈管理員進行操做,對新用戶進行合約部署權限受權 PEMManager pem = context.getBean(PEMManager.class); ECKeyPair pemKeyPair = pem.getECKeyPair(); //一、鏈管理員操做 受權新用戶的能夠發佈和部署合約 credentials = Credentials.create(pemKeyPair); PermissionService permissionService = new PermissionService(web3j, credentials); String s = permissionService.grantUserTableManager("t_item2",tempAddress); System.out.println("s = " + s);//這個是受權狀態 //二、使用新用戶進行表更新 操做 Credentials userCredentials=Credentials.create(tempPriKey,tempPublicKey); //完成後,測試表操做中update操做看看是否能夠成功 CRUDService crudSerivce = new CRUDService(web3j, userCredentials); String tableName = "t_item2"; String key = "name"; Table table = new Table(tableName, key); int num = 5; table.setKey("q");//查詢記錄sql語句必須在where子句中提供表的主鍵字段值。 Entry updateEntry = table.getEntry(); updateEntry.put("item_id", "徐徐吹v下次v"); updateEntry.put("item_name", "121212"); Condition updateCondition = table.getCondition(); updateCondition.EQ("name", "q"); updateCondition.EQ("item_id", "aaaaa"); int updateResult = crudSerivce.update(table, updateEntry, updateCondition); Assert.assertEquals(updateResult, num); //結果測試成功,使用受權用戶操做的表,能夠進行更新操做;不然,不具有這個權限的用戶,是沒法操做的 } }
根據本篇教程,能夠完成底層權限設置、以及sdk實際權限控制操做、最後實現數據上鍊等等。讀者能夠根據本身的業務需求修改表結構,依照上述流程能夠在生產環境中大體進行業務開發。
系列教程到此,暫時告一段落,基本從頭至尾能夠按照每一章節對FISCO BCOS 流程從頭至尾進行一次模擬生產環境的實踐。
讀後感受不錯,有收穫能夠微信請做者喝杯咖啡,讀後有疑問請加微信,拉羣研討,註明來意
原文出處:https://www.cnblogs.com/linbin524/p/11303365.html