仔细一想做事总得有始有终,挖个坑也不是不填,虽然最终没有做出来一个完全的软件,但是也能证明我是研究过区块链的嘛
话不多说,先上个Solidity代码
pragma solidity ^0.4.0;
contract Authorization{
uint private numRegisters;//统计系统已注册用户数
mapping(address => User) private users;//用户信息
mapping(uint => address) public coinToOwner;//代币ID找到对应用户
mapping(uint => address) private coinApproval;//代币授权映射
mapping(address => au) private verifier;
uint seed = 16 ** 10;
struct au{//用来存取身份认证的数字签名
uint s;
uint R;
uint X;
}
struct User{
string name;//用户名
uint ID;
bytes32 password;
bool hasRegistered;//表示是否注册
bool hasLogin;//表示是否登录
uint coins;//用户所有的代币数量
}
uint[] public coin;//定义代币,使用数组保存是因为可以扩充代币蕴含内容,为今后做准备
event Transfer(address _from, address _to, uint _coinId);
event Register(address _user, string _name, string _password);
event Login(address _user, string _name, uint _ID, string _password);
event Modify(address _user, string _newName, string _newPassword);
event Logout(address _user);
modifier onlyLogin(address _user){//只有注册且登录的账户才能访问功能
//主要是为了防止用户退出账户后又回退到主界面然后转账
require(users[_user].hasRegistered && users[_user].hasLogin);
_;
}
function register(string name,string password) payable public returns(uint){//用户注册函数
if(users[msg.sender].hasRegistered){//该用户已注册
return 0;
}else{//未注册就将用户信息存入users映射数组中
numRegisters++;
users[msg.sender].name = name;
users[msg.sender].ID = numRegisters;
users[msg.sender].password = sha256(password);
users[msg.sender].hasRegistered = true;
users[msg.sender].hasLogin = false;
users[msg.sender].coins = 1;//系统在你注册时赠送一枚代币
coin.push(numRegisters);//代币总量+1
coinToOwner[coin.length]=msg.sender;//这枚代币的所有者为当前用户
Register(msg.sender, name, password);//调用Register事件
return numRegisters;
}
}
function login(uint _id, uint s, uint X, uint R) view public returns(bool){//用户登录函数
//R = G(r),X = G(x),e = SHA256(R), s = r + F(e, x);
//为了体现出合约具有验证性,这里用用户注册时的密码来生成e
//如果生成的e经过计算可以得到正确的结果,就说明用户输入的密码正确
uint r = bytesToInt(users[msg.sender].password);
uint e = bytesToInt(sha256(G(r)));
if(G(s) == R + F(e, X)){
return true;
}else{
return false;
}
}
function modify(string newName,string newPassword) payable public {//身份信息修改函数
users[msg.sender].name = newName;
users[msg.sender].password = sha256(newPassword);//仅修改用户名和密码
users[msg.sender].hasLogin = false;//由于修改了密码,所以需要重新登录
Modify(msg.sender, newName, newPassword);//调用Modify事件
}
function logout() view public onlyLogin(msg.sender){//用户账号退出函数
users[msg.sender].hasLogin = false;//登录状态置为未登录
Logout(msg.sender);
}
function _transfer(address _from, address _to, uint _coinId) payable public onlyLogin(msg.sender){
//一次只能转一枚代币
users[_from].coins--;//转账者代币减一
users[_to].coins++;//接收者代币加一
coinToOwner[_coinId] = _to;//这枚代币所有者变成接收人
Transfer(_from, _to, _coinId);
}
function transfer(address _to, uint _coinId, uint e) public onlyLogin(msg.sender) returns(bool){//转账函数
//这个转账函数只用于代币权限设置,不交易代币
require(_to != msg.sender);
if(coinToOwner[_coinId] != msg.sender){
return false;
}
coinApproval[_coinId] = _to;//将代币所有权授予给收款方
//此时代币还在当前用户这里,因为还没有执行转账,必须接受方来收款后才能转移
//然后记录用户数字签名,即付款方给收款方签名,所以签名保存到收款方地址下
//这里将代币id作为随机盐值,用户id作为私钥,X即为公钥
uint r = bytesToInt(sha256(_coinId));
uint x = bytesToInt(sha256(users[msg.sender].ID));
uint R = G(r);
uint X = G(x);
uint s = r + F(e, x);
//数字签名形式为(s,R,X)
verifier[_to].s = s;
verifier[_to].R = R;
verifier[_to].X = X;
return true;
}
function receiver(uint _coinId, uint e) public returns(uint){
//对接收方进行验证
if(coinApproval[_coinId] != msg.sender){
//如果该金币尚未授权给该用户
return 0;
}
uint s = verifier[msg.sender].s;
uint R = verifier[msg.sender].R;
uint X = verifier[msg.sender].X;
uint s1 = R + F(e, X);
uint s2 = G(s);
if(s1 != s2){
//交易信息错误
return 2;
}
//验证无误后正式转账,返回转账后余额
_transfer(coinToOwner[_coinId], msg.sender, _coinId);
return users[msg.sender].coins;
}
function bytesToInt(bytes32 x) view public returns(uint){
return uint(x)/1e75%100;
}
function PasswordCheck(string pwd) view returns(bool){
if(sha256(pwd) == users[msg.sender].password){
return true;
}else{
return false;
}
}
function getName() view returns(string){
return users[msg.sender].name;
}
function getId() view returns(uint){
return users[msg.sender].ID;
}
function getHasRegistered() view returns(bool){
return users[msg.sender].hasRegistered;
}
function getHasRegistered(address _user) view returns(bool){
return users[_user].hasRegistered;
}
function getBalance() public returns(uint){
return users[msg.sender].coins;
}
function G(uint x) internal returns(uint){
return x * 13;
}
function F(uint e, uint x) internal returns(uint){
return e * x;
}
}
智能合约的代码肯定是没有问题的,对Solidity感兴趣的朋友可以学习一下这个语言,与JavaScript相似,学起来很容易。