项目背景
项目是基于微众的webasefront和webasesign开发的,后端使用springboot
在项目的开发过程中,遇到一些问题,我们的项目是要打包到服务器里面执行的,智能合约的abi和地址存到配置文件里面,而且本项目需要的智能合约多达十几个,那么如果我们要去其他服务器上配置环境的话,需要一个个编译部署并将其复制过来,十分浪费时间精力且容易错误。
另一个就是一旦需要对智能合约进行修改或者重新部署,那么需要修改配置文件并重新打包。。。繁琐不堪
解决方法
然后经过教训之后在想,是不是通过预启动程序和全局变量把所有合约的abi和地址存起来,而不是在配置文件里写死,那么我们重新部署合约的时候只需要重新启动一下jar包就行了
开机自启动程序CommandLineRunner或者ApplicationRunner
这两兄弟其实用起来差不多唯一不同的就是参数不同,ApplicationRunner对参数进行了包装,我这里用的是CommandLineRunner。
CommandLineRunner和ApplicationRunner要做的就是在我们的容器加载完成之后自动运行的程序,所以说可以看作开机自启动程序。
@Component
public class MyCommandLineRunner implements CommandLineRunner
@Override
public void run(String... args) {
}
将我们要实现的类继承CommandLineRunner即可,然后在继承的run方法中发送一个post请求获得我们想要存下来的合约地址和abi
webasefront中有一个接口可以返回我们部署在webasefront上的所有合约的信息。
具体可看官方的文档在此 返回信息如下
全局变量
在得到所有的合约信息后,我选择用全局变量保存下这些合约的信息,类型为map, map中key是合约的名字,value为合约的abi或者合约地址
首先在配置文件application.yml中创建一个参数
contract:
map: {}
然后新建一个实体类,作为全局变量的保存
@Component
@ConfigurationProperties(prefix = "contract")
public class ContractDeployAddress {
private Map<String, String> map = new HashMap<>();
public Map<String, String> getMap() {
return map;
}
public void setMap(Map<String, String> map) {
this.map = map;
}
//KV存储,通过合约名获取合约地址
public String getContractAddress(String contractName){
return map.get(contractName);
}
}
在我们要使用的时候,只需要用@Autowired
自动注入即可,这样就不必在每次合约变动的时候重新修改配置文件了
在此基础上其实还可以加一个接口,刷新全局变量中的合约地址和abi,发生变动的时候重新获取一下就可以了