功能实现:
1.部署者部署合约,并使用账号注册
2.使用已注册账号登入账户才能进行后续对商品的发布和购买
3.对账号购买和发布的商品进行查看
4.实现商品转增
尚未实现功能:
1.该合约商品发布时商品id不能自动输入,需要发布者手动输入,较为繁琐
2.只能通过管理员身份(合约部署者)查看购买和发布记录
3.商品流转信息问题
4.商品到期自动下架问题
5.账户之间资金流动问题
pragma solidity 0.4.25;
pragma experimental ABIEncoderV2;
contract Bamboo {
address companyAccount = 0xdD870fA1b7C4700F2BD7f44238821C26f7392148; //公司账户地址
mapping(address => uint256) balanceMapping;
address owner;
// 定义用户结构体
struct Customer {
address customerAdd; //用户地址
string userName; //用户名
uint256 password; //用户密码
string[] buyedGoods; //用户购买的商品
string[] selledGoods; //用户发布的商品
}
// 定义用户账户地址数组
address[] palyer;
// 定义结构体存放正在售卖的商品
struct Goods {
uint256 goodId; //商品id
string goodName; //商品名字
uint256 price; //商品售卖价格
bool isBought; //商品是否已被购买
uint256 showTime; //商品展示时间
uint256 releaseTime; //发布时间
}
// 定义商品流转信息结构体
struct Flow {
address[] flow_address;
string[] flow_name;
uint256[] flow_money;
}
// 流转信息映射
mapping(uint256 => Flow) flowMapping;
// 定义正在售卖商品数组
uint256[] sellGoods;
// 定义用户成功登入数组
address[] logIn;
// 定义用户映射
mapping(address => Customer) customerMapping;
// 定义商品映射
mapping(uint256 => Goods) goodsMapping;
// 商品id对应的拥有者
mapping(uint => address) hasGoodsMapping;
// 构造函数
constructor() public {
owner = msg.sender;
}
// 约束函数调用者
modifier onlyOwner() {
require(owner == msg.sender);
_;
}
// 判断用户是否存在
function isPalyer(address _address) public view returns (bool) {
bool isExist = false;
for (uint256 index = 0; index < palyer.length; index++) {
if (_address == palyer[index]) {
isExist = true;
break;
}
}
return isExist;
}
// 判断商品是否存在
function isGoods(uint256 _id) public view returns (bool) {
bool isExist = false;
for (uint256 index = 0; index < sellGoods.length; index++) {
if (_id == sellGoods[index]) {
isExist = true;
break;
}
}
return isExist;
}
// 判断账户是否登入
function isLogIn(address _address) public view returns (bool) {
bool isExist = false;
for (uint256 index = 0; index < logIn.length; index++) {
if (_address == logIn[index]) {
isExist = true;
break;
}
}
return isExist;
}
// 用户注册事件
event RegisterUser(address _customAddress, bool isSuccess, string message);
// 用户注册
function addCustomer(
address _address,
string _name,
uint256 _password
) public {
bool exist = isPalyer(_address);
// require(, "The customer is exist");
if (exist == false) {
palyer.push(_address); //加入用户账户数组
// 将信息加入结构体
customerMapping[_address].customerAdd = _address;
customerMapping[_address].userName = _name;
customerMapping[_address].password = _password;
emit RegisterUser(_address, true, "注册成功");
} else {
emit RegisterUser(_address, false, "该地址已被注册,注册失败");
}
}
// 用户登入
// 登入事件
event sign_In(address _address, string message);
function signIn(address _address, uint256 _password) public {
if (
_address == customerMapping[_address].customerAdd &&
_password == customerMapping[_address].password
) {
emit sign_In(_address, "登入成功");
logIn.push(_address);
} else if (
_address == customerMapping[_address].customerAdd &&
_password != customerMapping[_address].password
) {
emit sign_In(_address, "密码错误,登入失败");
} else if (_address != customerMapping[_address].customerAdd) {
emit sign_In(_address, "该账号未注册,请先注册账号");
}
}
// 发布商品
// 发布商品事件
//发布者地址 商品id 商品名字 是否发布成功
event release_Goods(
address _address,
uint256 _id,
string _name,
string _message
);
function releaseGoods(
address _address,
uint256 _id,
string _name,
uint256 _price,
uint256 _showTime
) public payable {
bool again = isGoods(_id);
//要求先登入账户后再进行后续操作
bool success = isLogIn(_address);
if (success == false) {
emit release_Goods(_address, _id, _name, "发布失败,请先登入账户");
return;
} else if (success == true) {
// 要求输入的商品id不存在重复问题
require(
again == false && _id != 0,
"该商品id已被使用,或商品id不能为0,请重新输入"
);
emit release_Goods(_address, _id, _name, "商品发布成功");
// 将商品id加入数组
sellGoods.push(_id);
// 流转信息加入结构体数组
flowMapping[_id].flow_address.push(_address);
flowMapping[_id].flow_name.push(_name);
flowMapping[_id].flow_money.push(_price);
// 将商品信息加入结构体
customerMapping[_address].selledGoods.push(_name);
goodsMapping[_id].goodId = _id;
goodsMapping[_id].goodName = _name;
goodsMapping[_id].price = _price;
goodsMapping[_id].showTime = _showTime;
goodsMapping[_id].releaseTime = block.timestamp;
//到期自动下架
}
}
// 合约拥有者给合约账户地址充钱
function addBalance() public payable {}
// 获取当前账户余额
function getBalance() public view returns (uint256) {
return address(this).balance;
}
// 获取内部账户余额
function getCurrent(address _address) public view returns (uint256) {
return balanceMapping[_address];
}
// 向内部账户地址充值
function addCurrent(address _address, uint256 _money) public {
balanceMapping[_address] += _money;
}
// 购买商品
// 自身账号地址,卖方账号地址,需购买的商品id,需购买的商品名字,返回信息
event buy_Goods(
address _buyaddress,
address _selladdress,
uint256 _id,
string _name,
bool _isbought,
string _message
);
//输入己方地址 需购买的商品id 商品名字
function buyGoods(
address _address, //己方地址
address _selladdress, //卖方地址
uint256 _id,
string _name
) public {
//要求先登入账户后再进行后续操作
bool success = isLogIn(_address);
if (success == false) {
emit buy_Goods(
owner,
_address,
_id,
_name,
false,
"购买失败,请先登入账户"
);
return;
} else if (success == true) {
// 要求自己不能购买自己的东西,并且商品仍处于销售状态
require(_address != _selladdress, "您不能购买自己的商品哦!");
require(
goodsMapping[_id].isBought == false,
"该商品已经被购买了哦,请看看其他的呢"
);
if (
balanceMapping[_address] <
goodsMapping[_id].price + goodsMapping[_id].price / 10
) {
emit buy_Goods(
owner,
_address,
_id,
_name,
false,
"账户余额不足,请充值(温馨提示:账户余额需大于购买商品的价格和购买商品的10%手续费之和)"
);
return;
} else {
// 买方付款
balanceMapping[_address] -=
goodsMapping[_id].price +
goodsMapping[_id].price /
10;
// 卖方收钱
balanceMapping[_selladdress] += goodsMapping[_id].price;
// 公司收钱
balanceMapping[companyAccount] += goodsMapping[_id].price / 10;
// 商品地址变更
hasGoodsMapping[_id] = _address;
customerMapping[_address].buyedGoods.push(_name);
// 流转信息
flowMapping[_id].flow_address.push(_address);
goodsMapping[_id].isBought = true;
emit buy_Goods(
owner,
_address,
_id,
_name,
true,
"购买商品成功,请保管好您的商品"
);
}
}
}
// 商品流通过程
// 定义id结构体,存放地址,名字,钱三个数组
function flowprocess(uint256 _id) public view returns (address[]) {
return (flowMapping[_id].flow_address);
}
// 用户查看历史物品列表
// 查看该账号发布的商品 即所有发布过的商品
function underRelease(address _address) public view onlyOwner returns (string[]) {
return customerMapping[_address].selledGoods;
}
// 查看该账号已购买的商品
function underBuy(address _address) public view onlyOwner returns (string[]) {
return customerMapping[_address].buyedGoods;
}
// 商品转增 转增账号 被转增账号 商品id
event CustomertransferGoods(address _address,bool issuccess, string message);
function giveAway(address _addressing,address _addressed, uint _id) public returns(bool){
if(hasGoodsMapping[_id] != _addressing){
emit CustomertransferGoods(_addressing, false, '您不是该商品拥有者');
return;
}else if(hasGoodsMapping[_id] == _addressing){
hasGoodsMapping[_id] = _addressed;
emit CustomertransferGoods(_addressing, true, '转增成功');
return;
}
}
}