(五)基于区块链的投票系统的设计与实现

1、需求分析

1.1 用户群体分析

需要进行投票表决的学校小团体、商业董事会群体、政府人员等。

1.2 系统用途概述

本系统是一个基于区块链技术的线上投票系统。针对目前线上投票系统中出现的恶意刷票、数据安全、隐私泄露等问题,本系统结合区块链技术的去中心化、数据不可篡改、可匿名性等特点,可以保证投票系统的投票数据公正、公开、可验证、不可篡改,提高投票系统的可信任性。用户可以通过本系统进行投票项目的创建、规定投票时间、注册投票等操作,系统同时提供投票数据可追溯可验证的功能,旨在给用户构建一个更加高效安全的投票环境。

1.3 功能模块分析及数据要求

本系统的功能模块分为八个模块,如图1所示,分别为:登录模块、投票项目内容模块、注册码模块、起止时间模块、通知模块、注册模块、投票模块和结果模块。

1.3.1 登录模块

主要功能:可以通过该模块登录系统,若输错数据,则有弹出框提示。

所需数据:用户的以太坊账号和密钥。

1.3.2 投票内容模块

主要功能:可以通过该模块初始化投票项目的标题和选项内容。

所需数据:当前用户的以太坊账号,投票项目的标题和内容。

1.3.3 注册码模块

主要功能:可以通过该模块设置用户成为合格投票者所需的注册码。该模块需要加入加密算法功能,将注册码加密传输到服务区端。

所需数据:当前用户的以太坊账号,随机生成的注册码。

1.3.4 起止时间模块

主要功能:可以通过该模块设置投票者的注册起止时间和投票起止时间。

所需数据:当前用户的以太坊账号,注册起止时间、投票起止时间。

1.3.5 通知时间模块

主要功能:实时显示通过注册和投票的人数。

所需数据:当前用户的以太坊账号,注册的人数、投票的人数。

1.3.6 注册模块

主要功能:投票者通过该模块注册成为具有投票资格的投票者,若注册不通过会有弹出框。

所需数据:当前用户的以太坊账号,正确的注册码。

1.3.7 投票模块

主要功能:投票者通过该模块给候选者投票。

所需数据:当前用户的以太坊账号,投票内容。

1.3.8 结果模块

主要功能:在所有人都投完票或者投票截止时间到之后,该模块显示最终结果。

所需数据:投票项目的标题,候选者以及对应的票数。

 

图1. 功能模块示意图

 

 

2、总体设计

2.1 基本设计思路

本项目在以太坊的平台搭建,使用truffle开发测试框架,系统使用的网络环境为Ganache,并通过metamask进行交易。通过编写投票的智能合约,将合约部署到以太坊平台运行,实现对底层区块链的交互。所有后台的操作对用户透明,管理员和投票者只需通过前端的UI界面进行操作。

2.2 目录结构

在使用truffle框架的基础上,我们首先定下了需要使用的语言和框架:合约编写语言Solidity,前端框架bootstrap,后台与合约进行交互操作的web3js。 接着,在以上基础上,我们将项目大体上分为后端和前端,后端存放在js目录之下:

前端存放在src的目录下:

静态资源存放在:

基础配置以及注解都写在truffle-config.js中.

 

2.3 测试计划

在系统功能实现的过程中需要进行各种例子的测试,首先需要保证基本功能的实现,然后根据各种合法与非法的例子测试,总结出当前功能存在的问题,再进行修正,再测试,直到找不出问题为止。

 

 

3、详细设计

3.1 系统架构

图2是基于以太坊的去中心化的架构图,从图中我们可以看出区块链层的工作主要是对合约运行过程中产生的数据进行存储,以太坊平台提供了合约的编译和部署环境以及对区块链进行交互的接口,对数据的操作只需调用各种方法接口,而不用直接对区块链本身进行编码工作。前端与合约进行交互主要通过Web3js,Web3js主要任务就是对WEB前端用户的操作和合约内容进行连接,因此该处有大量的调度函数,里面定义了来自用户的各种功能要求函数,以及来自区块链层的各种数据返回指令。Web前端层的任务就是将系统的功能以图形界面的方式展现给使用该系统的人,因此在用户层的主要内容就是书写大量的html页面,通过各种消息触发方式实现所提到的需求。

3.2 管理员操作

管理员登录系统的流程图如图3右侧部分所示,首先管理员用管理员账号登录系统,同时登录metamask钱包进行交易,账号正确则进入投票项目内容模块。管理员开始设置项目的标题和选项内容,确认交易后进入注册码模块;管理员将加密的注册码传给后台,确认交易进入起止时间模块;管理员设置系统的注册起止时间和投票起止时间,随后确认交易进入通知模块;通知模块显示目前通过注册和投票的用户人数,若在规定时间内投票者都投完了票或者时间超过了投票的截止时间,投票结束并公布投票结果。

图2. 基于以太坊的去中心化架构

在上面提到的所有操作中,如果管理员用户更换metamask的账户,则交易失败,返回系统登录界面。

图3. 管理员和投票者的操作流程图

3.3 投票者操作

投票者的流程图如图3左侧部分所示,首先投票者用自己的以太坊账户登录系统,同时登录metamask钱包进行交易,账号正确则进入投票模块;如果投票者未注册投票项目,则投票者进入注册模块传输加密的注册码进行注册,若注册码正确,则投票者返回投票模块,选择自己意向的候选者进行投票,若该投票者是第一次投票,则投票成功且返回投票项目的截止时间;若不是则投票失败。若用户在投票截止时间之后登录系统,则直接跳转到公布投票结果模块。

在上面提到的所有操作中,如果用户在注册前更换metamask的账户,系统不受影响;若在注册后更换metamask账户,则新账户需要注册,但是由于用户使用注册码将之前的账户注册成功,所以新账户再次使用注册码会注册失败,且后续操作也不能完成。

 

 

4、编码实现

附录列举了投票模块的代码。

5、结果展示

5.1 登录

 

5.2 设置初始化投票项目

5.3 设置注册码

5.4 设置注册和投票的起止时间

5.5 通知模块

5.5 用户登录

 

5.6 用户注册

5.7 用户投票

5.8 结果

6、总结

本次报告说明了基于区块链投票系统的需求分析、总体设计、详细设计、编码实现和结果展示。通过本次实验我收获了许多关于如何在以太坊平台搭建DApp的知识,我发现前期多看书籍多查找资料的话,后期的编码会很顺利。下一步就是正式开始撰写毕设论文啦。

附录:

投票模块的前端代码:

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="utf-8">

<meta http-equiv="X-UA-Compatible" content="IE=edge">

<meta name="viewport" content="width=device-width, initial-scale=1">

<title>区块链投票</title>

<link href="css/bootstrap.min.css" rel="stylesheet">

<!-- for pkcs5pkey -->

<script src="components/googlecode/core.js"></script>

<script src="components/googlecode/cipher-core.js"></script>

<script src="components/googlecode/md5.js"></script>

<script src="components/googlecode/tripledes.js"></script>

<script src="components/googlecode/enc-base64.js"></script>

<!-- for crypto -->

<script src="components/googlecode/sha1.js"></script>

<script src="components/googlecode/sha256.js"></script>

<!-- for crypto, asn1, asn1x509 -->

<script src="components/yahoo/yahoo-min.js"></script>

<!-- for asn1x509(stohex)

<script src="http://kjur.github.io/jsjws/base64x-1.1.min.js"></script> -->

<script language="JavaScript" type="text/javascript" src="ext/jsbn.js"></script>

<script language="JavaScript" type="text/javascript" src="ext/jsbn2.js"></script>

<script language="JavaScript" type="text/javascript" src="ext/prng4.js"></script>

<script language="JavaScript" type="text/javascript" src="ext/rng.js"></script>

<script language="JavaScript" type="text/javascript" src="ext/rsa.js"></script>

<script language="JavaScript" type="text/javascript" src="ext/rsa2.js"></script>

<script language="JavaScript" type="text/javascript" src="ext/base64.js"></script>

<script language="JavaScript" type="text/javascript" src="asn1hex-1.1.js"></script>

<script language="JavaScript" type="text/javascript" src="rsapem-1.1.js"></script>

<script language="JavaScript" type="text/javascript" src="rsasign-1.2.js"></script>

<script language="JavaScript" type="text/javascript" src="x509-1.1.js"></script>

<script language="JavaScript" type="text/javascript" src="pkcs5pkey-1.0.js"></script>

<script language="JavaScript" type="text/javascript" src="asn1-1.0.js"></script>

<script language="JavaScript" type="text/javascript" src="asn1x509-1.0.js"></script>

<script language="JavaScript" type="text/javascript" src="components/sm2/crypto-1.1.js"></script>

<script language="JavaScript" type="text/javascript" src="ext/ec.js"></script>

<script language="JavaScript" type="text/javascript" src="ext/ec-patch.js"></script>

<script language="JavaScript" type="text/javascript" src="ecdsa-modified-1.0.js"></script>

<script language="JavaScript" type="text/javascript" src="components/sm2/sm3.js"></script>

<script language="JavaScript" type="text/javascript" src="components/sm2/sm3-sm2-1.0.js"></script>

<script language="JavaScript" type="text/javascript" src="components/sm2/ecparam-1.0.js"></script>

<script language="JavaScript" type="text/javascript" src="components/sm2/sm2.js"></script>

<script language="JavaScript" type="text/javascript">

/*

function doGenerate() {

var f1 = document.form1;

var curve = f1.curve1.value;

var ec = new KJUR.crypto.ECDSA({"curve": curve});

var keypair = ec.generateKeyPairHex();

f1.prvkey1.value = keypair.ecprvhex;

f1.pubkey1.value = keypair.ecpubhex;

}

*/

function doCrypt() {

var f1 = document.form1;

var curve = f1.curve1.value;

var msg = f1.msg1.value;

var msgData = CryptoJS.enc.Utf8.parse(msg);

var pubkeyHex = f1.pubkey1.value;

if (pubkeyHex.length > 64 * 2) {

pubkeyHex = pubkeyHex.substr(pubkeyHex.length - 64 * 2);

}

var xHex = pubkeyHex.substr(0, 64);

var yHex = pubkeyHex.substr(64);

var cipherMode = f1.cipherMode.value;

var cipher = new SM2Cipher(cipherMode);

var userKey = cipher.CreatePoint(xHex, yHex);

msgData = cipher.GetWords(msgData.toString());

var encryptData = cipher.Encrypt(userKey, msgData);

f1.sigval1.value = encryptData;

}

/*function doDecrypt() {

var f1 = document.form1;

var prvkey = f1.prvkey1.value;

var encryptData = f1.sigval1.value;

var privateKey = new BigInteger(prvkey, 16);

var cipherMode = f1.cipherMode.value;

var cipher = new SM2Cipher(cipherMode);

var data = cipher.Decrypt(privateKey, encryptData);

alert(data ? ‘解密成功,原文:‘ + data : ‘解密失败!‘);

}

function certCrypt() {

var certData = document.getElementById(‘txtCertData‘).value;

if( certData != "") {

var key = X509.getPublicKeyFromCertPEM(certData);

document.getElementById(‘txtPubKey‘).value = key.pubKeyHex;

}

var pubkey = document.getElementById(‘txtPubKey‘).value.replace(/\s/g,‘‘);

var pubkeyHex = pubkey;

if (pubkeyHex.length > 64 * 2) {

pubkeyHex = pubkeyHex.substr(pubkeyHex.length - 64 * 2);

}

var xHex = pubkeyHex.substr(0, 64);

var yHex = pubkeyHex.substr(64);

var cipherMode = document.getElementById(‘cipherMode‘).value;

var cipher = new SM2Cipher(cipherMode);

var userKey = cipher.CreatePoint(xHex, yHex);

var msg = document.getElementById(‘txtRawData‘).value;

var msgData = CryptoJS.enc.Utf8.parse(msg);

msgData = cipher.GetWords(msgData.toString());

var encryptData = cipher.Encrypt(userKey, msgData);

document.getElementById(‘txtCryptData‘).value = hex2b64(encryptData);

}*/

</script>

<style>

.bd-placeholder-img {

font-size: 1.125rem;

text-anchor: middle;

-webkit-user-select: none;

-moz-user-select: none;

-ms-user-select: none;

user-select: none;

}

@media (min-width: 768px) {

.bd-placeholder-img-lg {

font-size: 3.5rem;

}

}

</style>

<!-- Custom styles for this template -->

<link href="css/form-validation.css" rel="stylesheet">

</head>

<body class="bg-light">

<div class="container">

<div class="py-5 text-center">

<img src="images/title1.svg" width="" height="">

<h2 id="projectName"> </h2>

</div>

<div class="table-responsive">

<table class="table table-bordered" >

<thead>

<tr>

<th >选项</th>

</tr>

</thead>

<tbody>

<tr>

<td id="select1"></td>

</tr>

<tr>

<td id="select2"></td>

</tr>

<tr>

<td id="select3"></td>

</tr>

</tbody>

</table>

</div>

需要先注册才能进行投票哦,点击<a href="login.html">这里</a>进行注册!

<hr class="mb-4">

<!-- MAIN CONTENT -->

<div id="main_content_wrap" class="outer">

<section id="main_content" class="inner">

<!-- now editing -->

<form name="form1">

<div class="mb-3">

<label for="note">请按以下步骤进行投票:</label><br>

<label>1、系统生成的公钥</label><br/>

椭圆曲线加密名称:

<select name="curve1">

<option value="sm2">SM2

</select>

<!--input type="button" value="生成密钥对" onClick="doGenerate();"/><br/-->

<br>

<!--私钥 (十六进制): <input type="text"  class="form-control" name="prvkey1" id="prvkey1" /-->

公钥 (十六进制): <input type="text"  class="form-control" name="pubkey1" id="pubkey1" />

</div>

<hr class="mb-4">

<!-- ============================================================== -->

<label for="sig">2、加密选票</label><br>

加密方式:

<select id="cipherMode" name="cipherMode">

<option value="1" selected="selected">C1C3C2

</select><br/>

需要加密的选票内容:

<input type="text" name="msg1" class="form-control" value="" />

<input type="button" value="加密选票" onClick="doCrypt();"/><br/>

<hr class="mb-4">

<label for="data">3、加密后的选票 (十六进制)</label><br>

<p>

<input type="text" id="sigval1" class="form-control" name="sigval1" value="" />

</p>

<!--

<button class="btn btn-default btn-vote" type="button" >注册</button>

-->

</form>

<hr class="mb-4">

<button class="btn btn-primary btn-lg btn-block" type="submit">投票</button>

<!--

<button class="btn btn-default btn-vote" type="button" >投票</button><br>

-->

<!-- now editing -->

</section>

</div>

</div>

<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>

<script src="js/web3.min.js"></script>

<script src="js/truffle-contract.js"></script>

<script src="js/vote.js"></script>

<script src="js/bootstrap.min.js"></script>

</body>

</html>

<style>

.test-center{

text-align: center;

}

table{

width: 50%;

}

table tr{

border-bottom: 2px solid #efefef;

height: 40px;

}

</style>

 

 

 

 

 

投票模块的后端代码:

Vote = {

web3Provider: null,

contracts: {},

initWeb3: function () {

if (typeof web3 !== ‘undefined‘) {

Vote.web3Provider = web3.currentProvider;

} else {

Vote.web3Provider = new Web3.providers.HttpProvider(‘http://localhost:7545‘);

}

web3 = new Web3(Vote.web3Provider);

Vote.initContract();

},

initContract: function () {

$.getJSON(‘Voting.json‘, function (data) {

var Artifact = data;

Vote.contracts.Voting = TruffleContract(Artifact);

Vote.contracts.Voting.setProvider(Vote.web3Provider);

//console.log(Vote.contracts.Voting);

//Vote.setCounts();

});

Vote.handleRegister();

},

handleRegister: function() {

var Instance;

//var registerId = $("#registerId").val();

//console.log(registerId);

// 获取用户账号

web3.eth.getAccounts(function (error, accounts) {

if (error) {

console.log(error);

}

var account = accounts[0];

//console.log(account);

//$("#user_id").html(account);

Vote.contracts.Voting.deployed().then(function (instance) {

Instance = instance;

Instance.getProjectName.call({from:account}).then((Vote) => {

console.log("Success! Got Vote: " + Vote);

var projectName = Vote;

//alert(projectName);

$("#projectName").html(projectName);

}).catch((err) => {

console.log("Failed with error: " + err);

});

//var projectName = Instance.getProjectName().then(value => console.log(value));

//get select1

Instance.getCandidateList.call(0,{from:account}).then((Vote) => {

console.log("Success! Got Vote: " + Vote);

var select1 = Vote;

//alert(select1);

$("#select1").html(select1);

}).catch((err) => {

console.log("Failed with error: " + err);

});

//get select2

Instance.getCandidateList.call(1,{from:account}).then((Vote) => {

console.log("Success! Got Vote: " + Vote);

var select2 = Vote;

//alert(select1);

$("#select2").html(select2);

}).catch((err) => {

console.log("Failed with error: " + err);

});

Instance.getCandidateList.call(2,{from:account}).then((Vote) => {

console.log("Success! Got Vote: " + Vote);

var select3 = Vote;

//alert(select1);

$("#select3").html(select3);

}).catch((err) => {

console.log("Failed with error: " + err);

});

});

});

Vote.doGenerate();

},

doGenerate: function(){

var f1 = document.form1;

var curve = f1.curve1.value;

var ec = new KJUR.crypto.ECDSA({"curve": curve});

var keypair = ec.generateKeyPairHex();

//f1.prvkey1.value = keypair.ecprvhex;

f1.pubkey1.value = keypair.ecpubhex;

var prvkey1 = keypair.ecprvhex+" ";

var pubkey1 = f1.pubkey1.value;

var Instance;

// 获取用户账号

web3.eth.getAccounts(function (error, accounts) {

if (error) {

console.log(error);

}

var account = accounts[0];

//alert(account);

//console.log(account);

Vote.contracts.Voting.deployed().then(function (instance) {

Instance = instance;

Instance.doGenerate(prvkey1, {from: account});

//$("#prvkey1").html(prvkey1);

$("#pubkey1").html(pubkey1);

});

});

//$("#pubkey1").html(keypair.ecpubhex);

Vote.vote();

},

vote: function () {

$(document).on(‘click‘, ‘.btn‘, Vote.handleVote);

},

handleVote: function () {

var f1 = document.form1;

var VotingInstance;

// 获取用户账号

web3.eth.getAccounts(function (error, accounts) {

if (error) {

console.log(error);

}

var account = accounts[0];

//console.log(accounts);

Vote.contracts.Voting.deployed().then(function (instance) {

VotingInstance = instance;

VotingInstance.VaildID.call({from:account}).then((vaildornot) => {

console.log("Success! Got Vote: " + vaildornot);

if(!vaildornot){

alert("请先注册!");

window.location.href="login.html";

}

else{

VotingInstance.isVoted.call({from:account}).then((votedornot) => {

console.log("Success! Got Vote: " + votedornot);

if(votedornot){

alert("你已投过票!");

Vote.initWeb3();

}

else{

//get privatekey

VotingInstance.getPrivateKey.call({from:account}).then((result) => {

console.log("Success! Got result: " + result);

var prvkey = result;

console.log(prvkey);

var privateKey = new BigInteger(prvkey, 16);

//var prvkey = f1.prvkey1.value;

//console.log(prvkey);

var encryptData = f1.sigval1.value;

console.log(encryptData);

var privateKey = new BigInteger(prvkey, 16);

console.log(privateKey);

var cipherMode = f1.cipherMode.value;

console.log(cipherMode);

var cipher = new SM2Cipher(cipherMode);

console.log(cipher);

var data = cipher.Decrypt(privateKey, encryptData);

console.log(data);

var candidateName = data;

VotingInstance.voteForCandidate(candidateName, {from: account});

VotingInstance.getVoteEndTime.call({from:account}).then((result) => {

console.log("Success! Got result: " + result);

//VoteEndTime = new Date(result.replace(/-/g,"\/"));

alert("投票成功!结果将会于"+ result +"公布!")

}).catch((err) => {

console.log("Failed with error: " + err);

});

});

}

}).catch((err) => {

console.log("Failed with error: " + err);

});

}

}).catch((err) => {

console.log("Failed with error: " + err);

});

});

});

}

};

$(function () {

$(window).load(function () {

Vote.initWeb3();

});

});

 

 

 

 

原文地址:https://www.cnblogs.com/honghongzeng/p/12552146.html

时间: 2025-01-14 06:16:59

(五)基于区块链的投票系统的设计与实现的相关文章

(四)基于区块链的投票系统的设计与实现

基于区块链的投票系统的代码及前端页面实现 本次报告将介绍基于区块链的投票系统的实现过程,本系统的实现过程为:首先在总体设计及详细设计的基础上编写智能合约,在本地搭建的以太坊私有链节点上部署我们的智能合约,并设计与投票系统交互的前端界面,通过以太坊提供的通过以太坊提供 Web3.js 库的 JavaScript API 接口调用部署在区块链上智能合约的相应方法,实现整个投票系统的流程. 1.系统运行流程及需求分析 1.1 系统运行流程     1.2 需求分析 我们设计的投票系统主要分为两部分:投

(三)基于区块链的投票系统的设计与实现

1.本地环境的搭建(Windows 10) 1.1 安装nodejs,npm,git,web3,solc (1)nodejs:官网下载最新版本https://nodejs.org/en/download/current/ node.js后续还需安装python2.7与visual studio的c++开发工具包(建议手动). (2)npm:在Windows下安装nodejs会自带npm (3)git:官网下载即可https://git-scm.com/downloads (4)web3:命令行n

(一)基于区块链的投票系统的设计与实现之环境的搭建

由于博主的毕设做的是区块链的方向,因此想写博客记录这个过程. 博主是在本地搭建的开发环境,操作系统为window10,使用以太坊开发平台,truffle框架,Solidity开发语言,Atom编辑器. 如果你还不知道区块链的一些基础知识,推荐看完这个公开课: https://www.bilibili.com/video/av37065233 (1)安装Atom 官网:https://atom.io/ 点击进入官网,选择对应的版本下载安装即可. (2)安装Git, NodeJS, Truffle,

基于区块链的支付系统开发,区块链支付方案

基于区块链的支付系统开发,区块链支付方案区块链支付系统开发,区块链支付平台让用户轻松注册:每个人都知道,开一个新的账户或者买一张新的信.用.卡就意味着你需要花费大量的文书工作来完成冗长乏味的过程.而如果你使用数字资产区块链支付平台,你几乎肯定会立即这样做.此外,它就像应下载用程序到您手机一样简单. 区块链技术的去中心化特征正在"抢目前电商平台第三方支付平台的饭碗",以区块链为基础的新型互联网金融体系,买方和卖方可以直接交易,交易基于密码学原理而不基于信任,使得任何达成一致的双方,能够直

区块链开发(五)区块链ICO:互联网进化的驱动力

区块链开发(五)区块链ICO:互联网进化的驱动力 李赫 2016年10月8日 由于区块链不可篡改的特性,在众多区块链组织和公司的共同努力下,互联网将逐步从中心化的信任进化到由算法.数据为核心的去中心化信任.随着中心化的信任中介被逐渐削弱和替代,互联网的运作方式将被以区块链为代表的系统所改变.因此,区块链不仅是一种技术,更是一个关于互联网进化的故事,尽管这个故事还有些遥远,但它已经有了萌芽和初步的发展. 区块链ICO,正是符合去中心化趋势,通过全球众筹,可以将沉淀在全球的小额资金充分利用起来,形成

区块链快速入门(五)——区块链技术的演化

区块链快速入门(五)--区块链技术的演化 一.区块链技术的发展 比特币区块链面向转账场景,支持简单的脚本计算.如果引入更多复杂的计算逻辑,将能支持更多应用场景,即智能合约(Smart Contract).智能合约可以提供除了货币交易功能外更灵活的合约功能,执行更为复杂的操作.引入智能合约的区块链,已经超越了单纯数据记录功能:可以为区块链加入权限管理,高级编程语言支持等,实现更强大的.支持更多商用场景的分布式账本系统.区块链技术的三种典型演化场景如下: 二.区块链技术的分类 根据参与者的不同,区块

区块链产品溯源系统到数字资产交易系统开发技术

如何用区块链实现商品打假? 电影<我不是药神>最近比较火.片中除了动容的情节故事外,还有一些细节也给我们留下了深刻的印象,比如假院士卖假药的桥段. 为什么目前假货如此泛滥? 源中瑞jojo开发产品溯源带来了新的思路 具体来说,区块链技术开发电↑.可以从以下三个方面赋能零售商品的防伪溯源,并克服传统方式无法解决的痛点. 第一,基于不可篡改的商品信息,解决信任问题. 第二,全程实时溯源各种商品信息. 第三,有效遏制造假行为. 除了上述三点,区块链与零售业的结合,还可以显著提高效率.降低成本.具体而

基于区块链资产交易系统

基于区块链资产交易系统 今天先到这儿,希望对您 区块链,  技术领导力, 企业管理,系统架构设计与评估,团队管理, 项目管理, 产品管理,团队建设 有参考作用 , 您可能感兴趣的文章: 领导人怎样带领好团队构建创业公司突击小团队国际化环境下系统架构演化微服务架构设计视频直播平台的系统架构演化微服务与Docker介绍Docker与CI持续集成/CD互联网电商购物车架构演变案例互联网业务场景下消息队列架构互联网高效研发团队管理演进之一消息系统架构设计演进互联网电商搜索架构演化之一企业信息化与软件工程

基于区块链的播客,2019风口!

虽然youtube和soundcloud这样的平台已经成为独立音乐人的强有力的工具,这些平台同时也打开了内容管理方面的潘多拉魔盒.音频流媒体产业每年都在增长,在2018年底付费流媒体用户已经达到2.55亿人,该年度音乐流媒体销售产生的收入也接近了89亿美元.但问题在于:这些销售都是由大牌企业例如Spotify或者Apple Music主宰的,对于独立音乐人而言,要争取平台流媒体销售中的收入分成,其话语权并不够强大. 1.救星来了:区块链 区块链会出现在任何需要去中心化的解决方案中,对于音乐流媒体