区块链:使用Solidity和JavaScript

仔细一想做事总得有始有终,挖个坑也不是不填,虽然最终没有做出来一个完全的软件,但是也能证明我是研究过区块链的嘛

话不多说,先上个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相似,学起来很容易。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值