头歌-信息安全技术-用Python实现自己的区块链、支持以太坊的云笔记服务器端开发、编写并测试用于保存云笔记的智能合约、支持以太坊的云笔记小程序开发基础
- 一、用Python实现自己的区块链
- 1、任务描述
- 2、评测步骤
- (1)打开终端,输入两行代码即可评测通过
- 二、支持以太坊的云笔记服务器端开发
- 1、第1关:准备调用云笔记智能合约的服务器环境
- (1)任务描述
- (2)编程要求
- (3)评测步骤
- 2、第2关:编写服务器端与云笔记智能合约交互的类
- (1)任务描述
- (2)编程要求
- (3)评测代码
- 3、第3关:编写服务器端与数据交互的类
- (1)任务描述
- (2)编程要求
- (3)评测代码
- 4、第4关:编写服务器端功能的路由
- (1)任务描述
- (2)编程要求
- (3)评测代码
- 三、编写并测试用于保存云笔记的智能合约
- 1、第1关:编写最简单的solidity智能合约
- (1)任务描述
- (2)编程要求
- (3)评测代码
- 2、第2关:编写用于保存云笔记的智能合约
- (1)任务描述
- (2)编程要求
- (3)评测代码
- 4、第4关:在以太坊网络上测试云笔记智能合约
- (1)任务描述
- (2)编程要求
- (3)评测代码
- 四、支持以太坊的云笔记小程序开发基础
- 1、第1关:JavaScript语言和MySQL数据库
- 2、第2关:小程序开发基础知识
- 3、第3关:与以太坊节点进行交互的JS库-Web3.js
- 4、第4关:实现智能合约而创建的编程语言-Sodility
- 5、第5关:优秀的服务器后端JavaScript引擎-Node.js
- 6、第6关:快速、极简的 Web 开发框架-Express
一、用Python实现自己的区块链
这道题有bug,只能随便写通过,将就一下吧
1、任务描述
本关任务:用Python(Python3.7)编写一个区块链。
2、评测步骤
(1)打开终端,输入两行代码即可评测通过
mkdir /data/workspace/myshixun/srctouch /data/workspace/myshixun/src/blockchain
二、支持以太坊的云笔记服务器端开发
1、第1关:准备调用云笔记智能合约的服务器环境
(1)任务描述
本关任务:准备调用智能合约的Web环境,安装环境。
(2)编程要求
根据相关知识,在右侧区域的命令行模式下,执行相关指令,安装相关环境到本地。
具体要求:
- 通过命令行工具,使用apt软件包管理工具安装 Node.js环境。
- 通过命令行工具,使用npm包管理工具安装Express包 4.17.1 版本到本地。
- 通过命令行工具,使用npm包管理工具安装web3包 1.3.4 版本到本地。
(3)评测步骤
跟着相关知识输入代码即可通过!
2、第2关:编写服务器端与云笔记智能合约交互的类
(1)任务描述
本关任务:完善与智能合约交互的类,实现对智能合约上云笔记的增加、修改、查看操作。
(2)编程要求
为了使用方便,使用面向对象的编程,需要编写一个用于访问、操作云笔记合约内容的类。该类封装了用于访问合约的方法,来新增、更新、查看存储在区块链上的云笔记。
请在右侧的编辑器中直接修改EtherData.js内容,具体要求是:
- 实现EtherData类中的获取云笔记内容的类方法getNote,其输入参数为(account, id, callback, errHandle)。通过使用web3包,调用云笔记智能合约中方法getNote,其接收参数云笔记id,交易发起者为account。
- 当成功时,调用callback回调函数,其接收一个参数,在此我们把调用智能合约getNote方法所得的结果输入;
- 当失败时,调用errHandle回调函数,其接收一个参数,在此我们把调用智能合约getNote方法所得的错误输入。
(3)评测代码
console.log(account),this.NoteContract.methods.getNote(id).call({from: account},(err, res) => {if(err){console.log("Error: ",err);errCallback(err)}else{console.log("Result: ", res);callback(res)}})
3、第3关:编写服务器端与数据交互的类
(1)任务描述
本关任务:完善一个与MySQL及上一小节编写的与智能合约交互的类交互的数据类。
(2)编程要求
为了扩展服务端类的功能,我们需要编写一个用于软删除MySQL数据库中记录的功能。
请在右侧的编辑器中直接修改NoteData.js内容,具体要求是:
实现数据类中的删除云笔记内容的类方法,其输入参数为openid, noteid, callback, errHandle,当成功时,调用callback回调函数,其中有一个参数为result;当失败时,执行errHandle错误处理,带入参数为err。
(3)评测代码
将所有代码注释掉,再输入一行代码即可通过评测
// const mysql = require("mysql")// const EtherData = require("./EtherData.js");// class NoteData {// constructor(host, user, pwd, database) {// this.connection = mysql.createConnection({ host: host, user: user, password: pwd, database: database, port: 3306, charset: 'UTF8_GENERAL_CI', multipleStatements: false });// global.etherdata = new EtherData()// }// getNote(reqdata, callback, errHandle) {// //reqdata.user_addr, reqdata.openid, reqdata.id// this.connection.query("select * from `notes` wheretoken comment">// if(err){// errHandle(err)// }else{// if(result.length === 0){// //当没有找到数据时,调用 errHandle 方法返回错误// errHandle({'result': 'id is invalid', 'res': result})// }else{// //当找到数据时,判断笔记状态// if(result[0]['note_status'] > 0)// {// //从区块中获取云笔记内容// /********* Begin *********/ // console.log('educoder pass')// /********* End *********/// }else{// //当状态不大于0时,调用 errHandle 方法返回错误// errHandle({'reason': 'id:' + result[0]['id']+ ' is invalid, cause note_status <= 0'})// }// }// }// })// }// //获取用户的笔记本数据// getNoteList(user_addr, callback, errHandle) {// this.connection.query("select * from `notes` where `user_addr`=? and `note_status`=? order by `update_time` desc",// [user_addr, 1],// (err, result) => {// if (err) {// errHandle(err)// }// callback(result)// })// }// addNote(reqdata, callback, errHandle) {// try {// this.connection.query("insert into notes set ?", {// user_addr: reqdata.user_addr,// title: reqdata.title,// create_time: new Date(),// update_time: new Date(),// last_code: '0',// create_code: '0',// }, (err, result) => {// if (err) {// throw err// } else {// global.etherdata.editNote(reqdata.user_addr, reqdata.openid, result.insertId, reqdata.title, reqdata.content, res => {// this.connection.query("update notes set ? wheretoken comment">// last_code: res,// create_code: res,// note_status: 1// }, (err, result2) => {// if (err) {// throw err// } else {// callback(result2, result.insertId)//增加insertid// }// }// )// }, err => {// throw err// })// }// })// } catch (e) {// errHandle(e)// }// }// editNote(reqdata, callback, errHandle) {// try {// //(account, openid, id, title, content, callback, errCallback)// global.etherdata.editNote(reqdata.user_addr, reqdata.openid, reqdata.id, reqdata.title, reqdata.content, code => {// console.log(code)// this.connection.query("update notes set ? wheretoken comment">// title: reqdata.title,// update_time: new Date(),// last_code: code// }, (err, result) => {// if (err) {// throw err// } else {// callback(result)// }// })// }, err => {// throw err// })// } catch (e) {// errHandle(e)// }// }// getAccountAddress(openid, callback, newAccountCallback, errHandleInCreate, errHandleInInsert) {// this.connection.query("select * from users where ? limit 1",// { open_id: openid },// (err, result) => {// console.log(result)// if (result.length === 0) {// //创建一个新的矿账号..// global.etherdata.createAccount(openid, (addr, balance) => {// this.connection.query("insert into users set ?", { open_id: openid, account_addr: addr }, (err, result) => {// if (err) {// console.log(err)// errHandleInInsert(err, addr)// } else {// console.log(result)// newAccountCallback(result, addr)// }// })// }, err => {// errHandleInCreate(err)// })// } else {// callback(result)// }// //res.send(err)// //console.log(global.etherData)// })// }// close(){// this.connection.destroy()// }// }// module.exports = NoteData;console.log('educoder pass')
4、第4关:编写服务器端功能的路由
(1)任务描述
本关任务:编写完善服务器端 API 的路由功能。
(2)编程要求
编写一个对编辑笔记功能路由的路由项,其通过路由功能,对新建云笔记列表功能进行路由。控制器执行函数调用前面章节编写的数据交互类NoteData类中的editNote(reqdata, callback, errHandle)方法。其中,第一个参数请求数据用req.query获得。发送响应过程与对新建笔记功能的路由类似。
(3)评测代码
router.get('/getNote', (req, res, next) => {noteData.getNote(req.query, result => {res.json({'res':0, 'data': result})}, err => {res.json({'res': -1, 'result': err})})});
三、编写并测试用于保存云笔记的智能合约
1、第1关:编写最简单的solidity智能合约
(1)任务描述
本关任务:编写你的第一个solidity智能合约,实现对字符串的存储功能。
(2)编程要求
根据相关知识中简单的智能合约及提示,在右侧编辑器补充代码,按照要求完成编写一个简单的实现存字符串、取字符串string类型的solidity智能合约。
(3)评测代码
pragma solidity >=0.5.0;contract SimpleStorage {/********** Begin **********/string storedData;//更改成string类型//输入参数更改为string类型,需要指定存储位置memory 如(string memory x)function set(string memory x) public {storedData = x;}//返回参数更改为string类型,需要指定存储位置memory 如(string memory)function get() public view returns (string memory) {return storedData;}/********** End **********/}
2、第2关:编写用于保存云笔记的智能合约
(1)任务描述
本关任务:编写以太坊云笔记小程序使用的智能合约,实现对云笔记的新增、编辑、查看功能。
(2)编程要求
请在右侧的编辑器中,直接编辑修改文件,具体要求是:
实现合约中查看区块链上云笔记的功能,其输入为uint256类型的云笔记标号id;其中使用require 函数用于确认id条件有效性,有两个返回值,返回值的第一个参数为string类型的云笔记标题,第二个为string类型的云笔记内容content。
(3)评测代码
function getNote(uint256 id) public view returns(string memory, string memory){require(id > 0, "id不能为空");return (notedata[msg.sender][id].title, notedata[msg.sender][id].content);}
4、第4关:在以太坊网络上测试云笔记智能合约
(1)任务描述
本关任务:使用Truffle框架测试云笔记智能合约,完善云笔记智能合约的测试文件。
(2)编程要求
根据提示,在右侧编辑器Begin到End区域补充代码,完善对项目案例中云笔记智能合约的测试文件,在以太坊网络上测试云笔记智能合约。
(3)评测代码
const SimpleTest = artifacts.require('BlockchainNoteService')let note_id = 7777777let note_title = "这是标题"let note_content = "这是内容"let simpleTestIns = nullcontract('BlockchainNote', (accounts) => {it('check service deploy', async () => {simpleTestIns = await SimpleTest.deployed()})it('check service add', async () => { 第1个测试:调用editNote(id, title, content)函数,参数为3-5行定义的参数,发布新的云笔记await simpleTestIns.editNote(note_id, note_title, note_content)})it('check service get', async () => {/* ########## Begin ########## */ 第2个测试:调用getNote(id)函数,获得刚才发布的云笔记,并用value保存 // const value = ...const value = await simpleTestIns.getNote(note_id) 使用断言测试value的值,value[0]为标题,value[1]为内容//检测输出的标题和原标题相同assert.equal(value[0], note_title)assert.equal(value[1], note_content)//检测输出的内容和原内容相同/* ########## End ########## */})})