安装公共依赖
sudo apt-get install -y apt-transport-https ca-certificates software-properties-common
sudo apt-get install -y unzip git curl wget vim tree jq
安装gradle
cd /tmp && wget https://services.gradle.org/distributions/gradle-6.4-bin.zip
unzip gradle-6.4-bin.zip
sudo mv gradsle-6.4 /usr/local/gradle
#修改配置文件
sudo cat >> ~/.bashrc <<EOF
export PATH=$PATH:/usr/local/gradle/bin
EOF
#使配置文件生效
source ~/.bashrc
需要安装的七个docker镜像(版本不确定是否有影响)
下载docker-compose
wget https://get.daocloud.io/docker/compose/releases/download/1.25.3/docker-compose-`uname -s`-`uname -m`
sudo mv docker-compose-`uname -s`-`uname -m` /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose -v #检查是否安装成功
java环境
java -version
#如果没有java环境,用下列命令安装
sudo apt-get install -y openjdk-8-jdk
下载workspace
工作目录(将下载的workspace放在用户的home目录下即可)
git clone https://gitlab.com/qubing/blockchain_lab_v2.git ~/workspace
确保workspace下有以下的文件和文件夹
使用虚拟机进行实验可安装gui,使用云服务器进行实验可以在云服务器上安装gui然后通过vnc进行连接,安装gui过程参见https://blog.csdn.net/Linrena/article/details/106309969
因为workspace
目录下的chaincode
目录下有一个example01
项目,主要是让大家熟悉chaincode怎么编写。
使用IDEA打开example01
下的java
项目,该项目是一个gradle
项目,等待项目建立完成之后,打开MyContract.java
文件,查看初始的智能合约代码。
在workspace
文件夹下使用下列命令来体验如何部署一个区块链网络
#检测区块链网络的环境,初始化区块链网络,并且建立每个区块链网络的结点
. ./init.sh
#检测结点是否正常运行(当执行startup脚本时出现docker镜像问题时,是因为startup脚本本身的问题)
. ./startup.sh
#部署example01的chaincode
. scripts/deploy_chaincode.sh java ${PWD}/chaincode/chaincode_example01/java mycc_java
#测试example01的chaincode
. scripts/test_example01.sh mycc_java
#清空区块链网络环境
. ./teardown.sh
解决startup.sh
脚本执行错误:更改startup.sh
中的DB_IMAGE_TAG
,将原来的DB_IMAGE_TA
替换成DB_VERSION
为了更好的熟悉这个项目,我们来新增一个GetValue
和SetValue
方法,并将其部署区块链网络上
/**
*SetValue
*@param ctx context
*@param key key
*@param value value
*/
@Transaction(name = "SetValue",intent = Transaction.TYPE.SUBMIT)
public void SetValue(final Context ctx, final String key, final String value){
ChaincodeStub stub = ctx.getStub();
stub.putStringState(key,value);
}
/**
*GetValue
*@param ctx context
*@param key key
*@return value state in ledger
*/
@Transaction(name = "GetValue",intent = Transaction.TYPE.EVALUATE)
public String GetValue(final Context ctx, final String key){
ChaincodeStub stub = ctx.getStub();
return stub.getStringState(key);
}
进行单元测试(需要进行实际的测试,看单元测试是否通过)
@Nested
class InvokeSetValueTransaction {
@Test
public void SetValue() {
MyContract contract = new MyContract();
Context ctx = mock(Context.class);
ChaincodeStub stub = mock(ChaincodeStub.class);
String key = "truth";
String value = "ferron is a good boy";
when(ctx.getStub()).thenReturn(stub);
contract.SetValue(ctx,key,value);
InOrder inOrder = inOrder(stub);
inOrder.verify(stub).putStringState(key, value);
}
}
@Nested
class InvokeGetValueTransaction {
@Test
public void GetValue() {
MyContract contract = new MyContract();
Context ctx = mock(Context.class);
ChaincodeStub stub = mock(ChaincodeStub.class);
String key = "truth";
when(ctx.getStub()).thenReturn(stub);
when(stub.getStringState(key)).thenReturn("ferron is a good boy");
assertThat(contract.GetValue(ctx,key).equals("ferron is a good boy"));
}
}
重新部署example01
目录下的java
项目(不需要进行测试chaincode),具体部署方式参见第二部分,部署之前一定要确保已经执行过teardown.sh
脚本
在scripts
目录下新建一个的new_test_example01.sh
脚本,并且将原来的test_example01.sh
脚本复制到新建的脚本内,并且修改脚本,新增Getvalue
和SetValue
方法的脚本
测试部署的chaincode
. scripts/new_test_example01.sh mycc_java
example02项目是一个钱包的chaincode,初始java代码中包含Init
,Query
和Transfer
三种方法,功能分别是初始化钱包账户和余额,查询钱包余额,两个钱包之间进行转账。
现在我们新增一个Recharge
方法,用于给一个账户充值。
@Transaction(name = "Recharge", intent = Transaction.TYPE.SUBMIT)
public void recharge(final Context ctx, final String keyAccount, final String valueTrans){
ChaincodeStub stub = ctx.getStub();
//get value of account
String value = stub.getStringState(keyAccount);
// account not existing
if (value.isEmpty()) {
String errorMessage = String.format(Message.ACCOUNT_NOT_EXISTING.template(), keyAccount);
System.out.println(errorMessage);
throw new ChaincodeException(errorMessage);
}
//type conversion
int intValue = Integer.parseInt(value);
int intValueTrans = Integer.parseInt(valueTrans);
intValue+=intValueTrans;
stub.putStringState(keyAccount,String.valueOf(intValue));
}
进行单元测试
@Nested
class InvokeRechargeTransaction {
@Test
public void whenAccountExists() {
MyContract contract = new MyContract();
Context ctx = mock(Context.class);
ChaincodeStub stub = mock(ChaincodeStub.class);
String keyAccount = "A";
String valueRech = "100";
when(ctx.getStub()).thenReturn(stub);
when(stub.getStringState("A")).thenReturn("100");
Throwable thrown = catchThrowable(() ->{
contract.recharge(ctx,keyAccount,valueRech);
});
assertThat(thrown).isNull();
}
@Test
public void whenAccountNotExists(){
MyContract contract = new MyContract();
Context ctx = mock(Context.class);
ChaincodeStub stub = mock(ChaincodeStub.class);
String keyAccount = "A";
String valueRech = "100";
when(ctx.getStub()).thenReturn(stub);
when(stub.getStringState("A")).thenReturn("");
Throwable thrown = catchThrowable(() ->{
contract.recharge(ctx,keyAccount,valueRech);
});
assertThat(thrown)
.isInstanceOf(ChaincodeException.class)
.hasNoCause()
.hasMessage(String.format(MyContract.Message.ACCOUNT_NOT_EXISTING.template(),"A"));
}
}
部署chaincode
. scripts/deploy_chaincode.sh java ${PWD}/chaincode/chaincode_example02/java mycc_java02
将原来的test_example02.sh
复制一份并且进行以下修改
测试chaincode
. scripts/new_test_example02.sh mycc_java02
只显示上边框 table frame=above 只显示下边框 table frame=below 只显示左、右...
1.使用window.onresize let myChart = echarts.init(document.getElementById(do...
我们只需要简单地打开任意文本编辑器,将下面的代码复制进去,然后保存文件,例...
vue项目在开发环境下,让项目运行起来,是通过npm run dev命令,原理是在本地搭...
直接给span标记的样式设定width属性,会发现不会产生效果。 如果设置display:blo...
前言 本文章供python初学者自学学习以后的话应该会每周末更新一次因为本人也是在...
2021杭电计算机考研数一英一408专业课考研经验贴 前言 考研准备 教材 其他 打基...
如何在IDEA上新建Maven后端并链接数据库 后台基础创建 maven IDEA配置maven和tom...
DQL查询数据 DQL Select完整的语法 练习用的sql脚本 指定查询字段 where 条件子...
前言 在linux中,Bash 脚本是很基础的知识,大家可能一听bash脚本感觉很高大上,...