以太坊智能合约入门项目-众筹项目

一、智能合约

智能合约(英语:Smart Contract)是一种旨在以信息化方式传播、验证或执行合同的计算机协议。智能合约允许在没有第三方的情况下进行可信交易。这些交易可追踪且不可逆转。智能合约概念于1994年由Nick Szabo首次提出。

以上解释来自于维基百科

由于缺少可信的执行环境,智能合约并没有被应用到实际产业中,自比特币诞生后,人们认识到比特币的底层技术区块链天生可以为智能合约提供可信的执行环境,以太坊首先看到了区块链和智能合约的契合,发布了白皮书《以太坊:下一代智能合约和去中心化应用平台》,并一直致力于将以太坊打造成最佳智能合约平台,所以比特币引领区块链,以太坊复活智能合约。

在区块链上运行的程序,通常称之为"智能合约",所以通常我们将区块链程序称之为智能合约,在区块链上,由事件驱动,以代码形式存在,可执行的特殊交易合同,它是代码与数据的集合,是以太坊的核心。

1. Solidity语言

Solidity是以太坊智能合约的编程语言,语法接近于JavaScript,是一种面向对象的语言,用于智能合约的开发,并能够编程成以太坊虚拟机(EVM)字节码部署到以太坊底层区块链网络上,文件扩展名以.sol结尾,一般用于:

  • 投票
  • 众筹
  • 封闭拍卖
  • 多重签名钱包

等对信任,安全和持久性要求较高的应用场景。

2.EVM

类似于JVM,EVM是以太坊虚拟机(Ethereum Virtual Machine),是以太坊智能合约的运行环境,每个以太坊节点中都包含EVM,EVM是一个隔离的环境,在EVM内部运行的代码与外部没有关联,EVM运行在以太坊节点上,我们将智能合约部署到以太坊区块链网络后,合约就可以在以太坊网络环境中运行了。

3. 运行步骤

  • 编译

    以太坊虚拟机上运行的是字节码,需要我们在部署之前对合约进行编译转成字节码和ABI(二进制接口,是智能合约的接口说明)

  • 部署

    合约部署就是讲编译好的合约字节码,通过外部账号以发送交易的形势部署到以太坊的区块链网络上,有实际矿工出块之后,才算真正部署成功。

  • 运行
  • 合约部署后,当需要调用这个智能合约的方式时,只需要向这个合约账户发送消息(交易)即可,通过消息触发后智能黑夜的代码就会在EVM中执行。

二、开发环境

目前而言,还没有特别完善的Solidity开发工具,现在可选性并不多,用的最多的是Remix,大家暂且先用这个吧

  • 文件夹

    最左边是文件夹管理,里面列出了当前的工作区里的文件,remix可以支持从本地文件夹读取文件。

  • 工作区

    正中间是工作区,工作区上半部是代码编辑区,在这里可以写solidity合约。
    下半部是日志区,在执行智能合约时,会显示transaction相关的信息。在输出日志的时候还可以查看Details和Debug信息。

  • 功能区
    最右边的是功能区,里面有编译,运行,设置和分析以及调试器和支持。

    在编译器点击Details可以查看编译细节,里面有NAME,METADATA,BYTECODE,ABI 等一些相关信息。

    在设置里面可以选择我们的编译器版本,和一些IDE的使用设置。

    功能区提供了三个运行环境

    • JavaScript VM: 模拟环境
    • Injected Web3: 可以通过Mist或者MetMask钱包提供
    • Web3 Provider: 通过IPC配置获取

在下面的众筹项目中,我们采用的是JavaScript VM,在该环境中,Remix由5个以太坊账户组成,每个账户存有100个以太币用于合约的测试

三、众筹项目

在该众筹项目中,包含了两个角色,关系为多对多。

  • Investor: 众筹赞助方
  • BySponsor:众筹发起方

为了对代码进行比较全面的解读,直接将注释写到代码中,不再单独取出代码块进行说明

// 声明solidity版本为0.4.24
pragma solidity ^0.4.24;
// 创建合约CrowFunding
contract CrowFunding {
//定义众筹赞助方结构体
    struct Investor{
        address addr; //赞助地址
        uint count ;  //赞助数量
    }
//定义众筹发起方结构体
    struct BySponsor{
        address addr;       //接收地址
        uint goalCount;     //众筹金额
        uint receiveCount;  //已经众筹到的金额
        uint investorNum;   //众筹次数
        mapping (uint =>Investor) investors; //用于保存多个众筹赞助方信息
    }

    uint bySponsorNum = 0 ;  //定义众筹发起方的ID号
    mapping (uint=>BySponsor) bySponsors; //定义映射用于保存多个合作发起方信息

//定义函数,用于生成众筹发起方对象
    function newBySponsor() payable {
        // 将合约发起方ID号增加1
        bySponsorNum++;
        /* 创建合约发起方对象
        众筹地址为:当前Accout地址
        众筹金额为:通过Value值设置
        */
        BySponsor memory bySponsor = BySponsor(msg.sender,msg.value,0,0);
        //将该众筹对象保存至映射bySponsors中
        bySponsors[bySponsorNum] = bySponsor;

    }
 /*定义函数,用于查看创建的众筹金额
 传入参数: bySponsorId   众筹发起方ID
 返回值:   goalCount    创建的众筹金额
 */
    function getGoalCount(uint bySponsorId) constant returns (uint){
         // 通过bySponsorId从映射bySponsors中取出对应的bySponsor对象
        BySponsor memory bySponsor = bySponsors[bySponsorId];
        //返回bySponsor对象的goalCount属性值
        return bySponsor.goalCount;
    }

 //定义函数,用于实现众筹赞助方的赞助功能,传入参数为众筹发起方ID号,并定义函数类型为payable
    function sponsor(uint bySponsorId)payable {
        // 通过bySponsorId从映射bySponsors中取出对应的bySponsor对象
        BySponsor storage bySponsor = bySponsors[bySponsorId];
        //设置合约代码可执行条件是赞助的金额必须>0
        require(msg.value >0);
        // 将赞助金额加入到bySponsor对象的receiveCount属性中
        bySponsor.receiveCount += msg.value;
        //众筹次数累加
        bySponsor.investorNum++;
        //将本次众筹赞助方信息保存至映射investors中
        bySponsor.investors[bySponsor.investorNum] = Investor(msg.sender,msg.value);
        //实现转账,从当前地址(众筹赞助方地址)转入bySponsor(众筹接收方地址),金额为Value中定义的值
        bySponsor.addr.transfer(msg.value);
    }

 //定义函数,用于获取已经众筹到的金额,传入参数为众筹发起方ID号
    function getReceiveCount(uint bySponsorId) constant returns (uint){
         // 通过bySponsorId从映射bySponsors中取出对应的bySponsor对象
        BySponsor memory bySponsor = bySponsors[bySponsorId];
        //返回bySponsor对象的receiveCount属性值
        return bySponsor.receiveCount;
    }
//定义函数,用于检查是否众筹金额是否达标,传入参数为众筹发起方ID号
    function checkComplete(uint bySponsorId) constant returns (bool){
         // 通过bySponsorId从映射bySponsors中取出对应的bySponsor对象
        BySponsor bySponsor = bySponsors[bySponsorId];
        // 判断设定的众筹金额是否有效(不为0),并且已经众筹到的金额是否大于等于创建的众筹金额
        if (bySponsor.receiveCount >= bySponsor.goalCount && bySponsor.goalCount >0){
            return true;
        }else {
            return false;
        }
    }
}

四、项目测试

智能合约运行步骤已在上文提到

1. 编译合约

  • 此处选择了自动编译,无需手动编译
  • 选择合约为CrowFunding

2. 部署合约

  • 点击Run标签
  • 选择JavaScript VM环境,账户随意选择一个即可
  • 选择对应的合约CrowFunding
  • 选择Deploy按钮进行合约部署

3. 运行合约

  • 运行newBySponsor函数创建众筹信息

调用方法

  • 查看被赞助前相关信息

调用方法查看众筹设定金额,已经众筹到的金额,是否众筹完成等信息,注意此时ID为1

  • 执行捐助函数

切换Account =>定义捐助金额 =>填写捐助对象(ID为1) =>执行sponsor

日志信息

  • 查看捐助后相关信息

再次执行捐助100后,查看结果

至此,该众筹案例代码测试完毕

文中代码已上传至github中

https://github.com/DiaboFong/constractDemos/blob/master/demoCrowFunding.sol

原文地址:http://blog.51cto.com/clovemfong/2169244

时间: 2024-10-24 22:27:50

以太坊智能合约入门项目-众筹项目的相关文章

rpc接口调用以太坊智能合约

rpc接口调用以太坊智能合约 传送门: 柏链项目学院 ??在以太坊摸爬滚打有些日子了,也遇到了各种各样的问题.这几天主要研究了一下如何通过rpc接口编译.部署和调用合约.也遇到了一些困难和问题,下面将向大家分享. rpc接口调用智能合约 先来编写一个简单的智能合约 contract Multiply7 { event Print(uint); function multiply(uint input) returns (uint) { Print(input * 7); return input

web3j开发以太坊智能合约快速入门(特别适合java和android开发者)

web3j简介 web3j是一个轻量级.高度模块化.响应式.类型安全的Java和Android类库提供丰富API,用于处理以太坊智能合约及与以太坊网络上的客户端(节点)进行集成. 可以通过它进行以太坊区块链的开发,而无需为你的应用平台编写集成代码. 可以快速启动dmeo示例 想要快速启动的话,有一个Web3j demo示例项目可用,演示了通过Web3j开发以太坊的许多核心特征,其中包括: 连接到以太网网络上的节点 加载一个以太坊钱包文件 将以太币从一个地址发送到另一个地址 向网络部署智能合约 从

2018年以太坊智能合约开发语言Solidity最佳IDEs

Solidity是一种以智能合约为导向的编程语言.这是一种只有四年的年轻语言,旨在帮助开发基于以太坊数字货币的智能合约. 理解它官方文档应该是学习Solidity的最佳来源:solidity.readthedocs.io 想在以太坊的网络上建立自己的加密货币吗?想拥有自己的初始代码产品吗?以下是您今天可以使用的最佳Solidity IDE. Remix IDE Remix IDE是基于浏览器的,并且集成了编译器.没有服务器端组件. 官网: https://remix.ethereum.orggi

深入以太坊智能合约 ABI

开发 DApp 时要调用在区块链上的以太坊智能合约,就需要智能合约的 ABI.本文希望更多了解 ABI,如为什么需要 ABI?如何解读 Ethereum 的智能合约 ABI?以及如何取得合约的 ABI? 数字猫合约 ABI ABI(Application Binary Interface) 如果理解 API 就很容易了解 ABI.简单来说,API 是程序与程序间互动的接口.这个接口包含程序提供外界存取所需的 functions.variables 等.ABI 也是程序间互动的接口,但程序是被编译

solidity编程开发语言——以太坊智能合约利器

这篇关于Solidity教程的博客展示了很多Solidity特性.本教程假定你对以太坊虚拟机和编程有一定的了解. 以太坊,"世界计算机"提供了一个非常强大的全球共享基础设施,使用名为Solidity的编程语言构建去中心化应用程序. 让我们开始我们的Solidity教程,介绍Solidity. 什么是Solidity? 以太坊Solidity是一种面向智能合约的高级语言,其语法与JavaScript类似.solidity是用于生成在EVM上执行的机器级代码的工具.solidity编译器获

以太坊智能合约项目-Token合约开发与部署

修订日期 姓名 邮箱 2019-09-05 brucefeng [email protected] 一. 钱包环境安装 以太坊钱包顾名思义,就是管理以太坊地址,存储以太坊Token的工具,再简单点说,任何区块链网络都需要我们有自己的账户,管理账户的软件可称之为钱包,无论是炒币的还是研究以太坊开发的,钱包都是必不可少的. 1.钱包分类 1.1 Mist 说到以太坊钱包,第一个要说的当然就是Ethereum官方钱包+浏览器 Mist.Mist是一个全节点钱包(全节点钱包通俗的来说就是同步了全部的以太

以太坊智能合约开发工具 Truffle 最佳入门指导1

Truffle是以太坊(Ethereum)智能合约开发的瑞士军刀,小巧好用,上手简单. 本篇文章主要展示如何用Truffle 开发第一个Ethereum智能合约. 1.准备工作:(本人针对window环境,如果是mac 或linux可以自行搜索其他教程) a.安装git bash :http://gitforwindows.org/ b.安装npm:https://jingyan.baidu.com/article/a17d528506d7f58098c8f2b0.html 2.安装Truffl

如何用python和flask以太坊智能合约开发

将数据存储在数据库中是任何软件应用程序不可或缺的一部分.无论如何控制该数据库都有一个该数据的主控.区块链技术将数据存储到区块链网络内的区块中.因此,只要某个节点与网络同步,它们就会获得区块中数据的副本.因此,该技术中没有特定的数据主控. 在本教程中,我们将编写一份智能合约(我将进一步解释),以便在区块链上保留用户数据.我们将使用python web3(web3的python库)来开发和部署智能合约.一旦我们在区块链上部署了智能合约.我们将使用flask API与智能合约进行交互以存储一些数据/信

通过一个案例精通以太坊智能合约和Solidity

作者介绍 Silver CEO 星际区块链信息发展有限公司 项目组件 ??这个项目是一个构建在以太坊上的游戏,感谢这个团队给我们提供的案例:https://cryptozombies.io ??从功能的角度看,有如下脚本: zombiefactory.sol:定义zombie和生成zombie. zombiefeeding.sol:定义小猫接口,给zombie吃小猫. zombieattack.sol:zombie打架的功能. erc721.sol:ERC721代币的接口. ownable.so