区块链项目实战 - 使用以太坊/智能合约solidity,全栈开发区块链借贷记账小应用,含完整源码
Posted 链巨人
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了区块链项目实战 - 使用以太坊/智能合约solidity,全栈开发区块链借贷记账小应用,含完整源码相关的知识,希望对你有一定的参考价值。
本文使用区块链平台以太坊+智能合约实现一个区块链记账的功能,具体为:
- 借款人和贷款人以及数额被记录在区块链中。使用区块链地址来表示借款人或者贷款人。
- 若一个借款人多次向一个贷款人借钱,更新所有的数额之和并记录在区块链中。
- 智能合约保存所有用户的借贷信息,包括他们的区块链地址和数额
- 只有借款人才能向智能合约中添加借款记录。
- 若一个人既是借款人,也是贷款人,那么最终下图中的“Total Owed”只显示他总的欠款。因此,如果他借出去的钱比借来的钱多,那么这个字段为0,表示他不欠任何人钱。
- 一个UI界面方便用户使用该应用。
除了智能合约部分的代码逻辑,还需要实现后台的UI和交互。这里使用javascript和html来实现。执行使用ganache在本地节点中来创建一个以太坊的测试环境。先看最终的html页面:
下面是执行环境安装和完整的源码的地址。
执行环境搭建
- 下载安装node.js (使用到了web3.js)
- 安装ganache-cli (用来模拟以太坊的本地环境)
- 通过下面的链接进入remix 的IDE: https://remix.ethereum.org/
- 编写智能合约,具体的智能合约见文末;
- 在本地电脑中启动ganache-cli。在cmd中输入命令“ganache-cli”,回车即可。
- 为了部署写好的智能合约,选择下图编号为1的选项,选择web3 Provider;点击Deploy按钮就可以将编译好的智能合约部署到本地的ganache-cli节点了。
- 点击上图编号3的图标复制智能合约的地址,(粘贴)作为代码script.js文件的contractAddress变量的值。
- 使用浏览器打开index.html文件,即可看到第一张图效果。
需要注意的内容
这里的代码只是一个demo,目的是演示一个全栈的以太坊智能合约应用,因此没有优化性能。这里的性能主要指的是js代码跟本地节点交互的成本。其次,为了减少智能合约的存储和计算开销,这里把大部分逻辑和存储放到了本地的js代码中。在目前的以太坊的mainnet中,交易费是很贵的。相比之下,js代码和本地节点的交互反而是很便宜的。特别的,调用“只读”的智能合约函数是不需要交易费的,因为这个过程只是js代码和本地节点的交互,并没有往区块链中写入或者修改区块链的数据。因此,script.js中的函数“downloadAll()”是不需要手续费的。
完整的源码下载:
https://github.com/liangyihuai/LearnBlockchainByCoding
完整的智能合约代码:
pragma solidity 0.6.6;
contract Splitwise
struct CreditAcc
address creditor; //the person who lends money
uint32 amount; //
//debtor address => creditor infor
mapping (address => CreditAcc[]) creditAccMap;
address[] users; //store all registered user's addresses.
function getUsers() public view returns(address[] memory)
return users;
//The debtor borrows money from the creditor
function lookup(address debtor, address creditor) public view returns (uint32 ret)
if(existCreditor(debtor, creditor))
CreditAcc[] memory ca = creditAccMap[debtor];
for(uint i = 0; i < ca.length; i++)
if(ca[i].creditor == creditor)
return ca[i].amount;
return 0;
function add_IOU(address creditor, uint32 amount)public
require(amount > 0);
require(msg.sender != creditor);
if(!existAnyCreditor(msg.sender))
CreditAcc[] storage creditAccArray;
creditAccArray.push(CreditAcc(creditor, amount));
creditAccMap[msg.sender] = creditAccArray;
else if(!existCreditor(msg.sender, creditor))
creditAccMap[msg.sender].push(CreditAcc(creditor, amount));
else
CreditAcc[] storage caArr = creditAccMap[msg.sender];
for(uint i = 0; i < caArr.length; i++)
if(caArr[i].creditor == creditor)
caArr[i].amount += amount;
if(!existUser(creditor)) users.push(creditor);
if(!existUser(msg.sender)) users.push(msg.sender);
//----------------------------------------------------------
//helper functions
//----------------------------------------------------------
function existAnyCreditor(address debtor) private view returns(bool)
if(creditAccMap[debtor].length == 0) return false;
return true;
function existCreditor(address debtor, address creditor) private view returns(bool)
if(!existAnyCreditor(debtor)) return false;
CreditAcc[] memory caArr = creditAccMap[debtor];
for(uint i = 0; i < caArr.length; i++)
if(caArr[i].creditor == creditor)
return true;
return false;
function existUser(address u)private view returns(bool)
for(uint i = 0; i < users.length; i++)
if(users[i] == u) return true;
return false;
以上是关于区块链项目实战 - 使用以太坊/智能合约solidity,全栈开发区块链借贷记账小应用,含完整源码的主要内容,如果未能解决你的问题,请参考以下文章