开源免费的EOS-ETHXLM收款插件

无需搭建比特币/以太坊/EOS全节点(每一个都需要几百G空间)无手续费,你的程序你做主所有收到的钱实时自动转移到开发者个人账户,即使被拖库也没钱可盗。GitHub 地址 开发者访问本地 http 接口,向用户展示付款方法,用户付款后程序会访问本地回调URL 步骤: 1. 创建一个Mixin Messenger账户.访问 https://mixin.one/messenger 下载对应手机端App。 中国大陆用户可以访问 https://a.app.qq.com/o/simple... 下载 2. 激活开发者账号登陆 https://developer.mixin.one ,用App扫码登录 这个 教程对于新开发者很有用。 Clone, build, rungit clone https://github.com/myrual/mixin-network-snapshot-golangcd mixin-network-snapshot-golang编辑一部分配置信息const ( userid = "3c5fd587-5ac3-4fb6-b294-423ba3473f7d" sessionid = "42848ded-0ffd-45eb-9b46-094d5542ee01" private_key = `-----BEGIN RSA PRIVATE KEY-----MIICXAIBAAKBgQDACTrT4uaB9el9qe0MUOsFrm8kpaDI9PowauMB1Ha25mpfL+5hMFqISLS5z2P89nAsXBg+KyQ2gAVA6rBwW/ZqOc1PKiJhhLBS80nzo3ayfv7OlzNGIxMyqD5izCCtPixnqpuTePoPWq4CNZlxop0VYklsWEfU0U0qqMBgmtqYfQIDAQABAoGAR8crZed5oTn5fC73m5LjRcxdXqVJ49MtcMuC7jwr41FckRepUkpwjGAgrRMHnJXAd9Q0e4hEkNppHEqciGLXR1dQfZnaM1Gnv7mD3oSgHaH+4qAMnNOCpvwW4Eu3yp9b1UGj9SvM3D2BrpA+MGf0E/yEJzpRcT956W6SPYYSegECQQDm4uTK+teoxr1ZagJZuCta+IhMzpxIWMob+JN/Huf7OnRcIa9JpXngg4tHOUWmZCDQdqeJMpaQc8SQ44hba015AkEA1OyJswNIhdmvVp5P1zgREVVRK6JloYwmAtj+Qo4pWJ117LqH4w+b491r4AeLEGh8VrZ4k6Hp+Cm783S2jTAWJQJARbWdlHdV45xVkQiDuyjy1h2RsXb0EpfUNcvAZLIlImIMvcBh1x+CA7pTs+Zj1BAJJEee37qJYQXDBGfeRJPKKQJAVG+cx42Ew/eoTZwoIzvLoOkJcFlNHjwaksSER9ZiVQ7URdVOr99vvXQAJG45Wn9k12oy9LCfvNan/wqIngK0tQJBAL1Wc02seEbMeWyt5jycJEhn6G8F18s9S1v0GXb4U/7/6Y87P3TmDLcEuCXkrbZQaCX7jVLu0BkDw8To58TWjh0= -----END RSA PRIVATE KEY-----` ADMIN_MessengerID = ""//this is your mixin messenger id, you can find your id in contact page.)编译go build mixin_snap.go运行./mixin_snap数据库同一目录下会生成一个test.db 的sqlite3文件。 如何使用获取数字资产当前价格信息,因此可以计算客户应该付多少数字资产curl -X GET 'http://localhost:8080/assetsprice'价格结果如下,其中Full Name是该币种全名,Symbol是在交易所和钱包的缩写符号,USDPrice是当前资产美元价格,BTCPrice同理。 ...

July 12, 2019 · 3 min · jiezi

二-用-JavaScript-写-DApp环境配置和编辑器配置

环境配置FIBOS 开发环境配置非常简单,只需要安装 FIBOS 即可。不过值得一提的是,目前 FIBOS 只支持 UNIX 系统,比如 Mac OSX,Linux 和 FreeBSD,但是不支持 Window 系统。不过 Window 用户装一个虚拟机就可以造起来啦! curl -s https://fibos.io/download/installer.sh | sh一行代码搞定,So easy! 赶紧试试 FIBOS 装好没。 fibos --version正常输出,棒! 编辑器配置理论上任何编辑器都可以,但是我选择了宇宙第一编辑器 VSCODE。因为 FIBOS DApp 基本上都是 js 文件,所以VSCODE 代码高亮基本上不用怎么配置就可以。 唯一需要配置的是 .abi文件。我们可以在 VSCODE 菜单栏中点击 preferences,搜索 files.associations,打开settings.json文件在最后添加: "files.associations": { "*.abi": "json" }这几行的代码意思就是把 .abi看做 json 文件进行代码高亮。 今天就分享到这里,下一篇文章进入正题。大家有兴趣也可以关注我的知乎专栏:https://www.zhihu.com/people/...

July 4, 2019 · 1 min · jiezi

一-用-JavaScript-写-DApp谈谈-ETHEOSFIBOS

一个普通开发者对 ETH、EOS、FIBOS的看法一直保持着如儿童般的好奇心和技术的热情,挺早就关注区块链和加密货币。当然并没有发财,这可能跟自己知识结构和本身比较穷有关。 在读大学的时候第一次听到了比特币,那时候可能几美元吧记不清了。后来接触到了以太坊,第一次听到了 DApp 这个词。可能当时各种资料比较少,只是看了看文档并没有真正尝试去写一个 DApp。 真正想着去编写一个 DApp 应该是在 2018 年,当时一句话感触至深: 你想真正了解一件事情最好的方法是参与其中。于是乎在 2018 年花了一点点钱买了一点点加密币。大家不用猜也知道,买在了山顶上,哈哈哈。也就是从那时候开始,在 Udemy 买了课程 Ethereum and Solidity: The Complete Developer's Guide 和 参加了 LoomNetWork 的在线互动课程。这两个课程质量非常好,强烈推荐,算是我的 DApp 入门课程。但是但是,我并没有后续自己独立开发出一个 DApp。 再后来,通过一直在微博上关注的西祠胡同响马,了解到了 FIBOS,也把自己为数不多的 EOS 兑换成了 FO。 为什么会关注 FIBOS 呢?经历了 Solidity 写 DApp 的确发现 Solidity 其实也有一定的学习成本,虽然说 Solidity 跟 Javascript 类似,但是还是有自己不同的语法。另外 DApp 编程,跟中心化应用你的大脑回路需要不一样。另外 ETH 一个缺点就是性能比较差,而且跑你的 DApp 非常贵。大家应该也听说过一个云养猫的 DApp 就让 ETH 拥堵不堪了。 当然 ETH 的开发团度肯定也意识到了这些问题,但是有号称区块链 3.0 的 EOS 出来想要解决这些问题。更快的运行速度,更大的通量,更便宜的运行成本,但是似乎并没有解决开发门槛的问题。目前 EOS 仅仅支持 C 和 C ++ 编写合约。EOS 比 ETH 开发门槛更高了。 ...

July 4, 2019 · 2 min · jiezi

为什么说Mixin-Network是POS版本的比特币

比特币的账本形成是需要一个困难的计算过程,从上一篇文章的角度出发可以知道任何尝试双花或者改账本的想法都必须付出电费+芯片投入成本。而且矿工挖矿不需要任何许可,任何人有电有网有钱都可以,因此甚至可以认为比特币通过将记账权力交给自由市场,无论是攻击者,还是愿意赚钱的矿工,都是自由市场上的参与者。攻击者如果要修改账本,意味着需要和整个自由市场里面的其他匿名参与者竞争。尽管表面看起来这不是一个消灭坏人的方法,但是比特币10年的历史已经证明通过自由市场竞争可以获得高度可靠的钱联网。 自由主义记账如何应用在POS?POS一直以来都是学者研究的领域,因为POS确认快而且不那么费电。根据文献:On Stake and Consensus所说,符合如下条件的POS是有机会实现一个靠谱的钱联网。 参与记账的节点是随机分布的,因此无法合谋即使他们合谋,他们的合谋也不会打击这个POS系统,因为他们自己还需要把自己锁定的资金拿回来,不能亏钱。他们合谋造成的破坏很有限该论文另外提出一个关键细节就是抵押的资产是否可以在该体系内继续创造出来。如果需要抵押的资产是必须从外部购买,那么该体系依然靠谱。但是如果该体系需要抵押的资产是体系内可以创造的,那么抵押资产就不值钱,因此抵押也就不值钱,因此就无法实现:潜在攻击者花费很多钱才能发起攻击。 很明显,符合以上条件的POS记账方法也是将记账权交给自由市场,从而实现高度可靠的转账和储值网络。 因为该系统节点需要且只需要质押自己的资产,意味着仅需投入金钱,无其他门槛。记账才能分钱,本身有竞争。篡改账本需要与其他节点竞争,要么合谋,要么掏出更多的资产抵押。合谋篡改账本会导致整个网络受到打击,质押的资产可能大幅贬值甚至归0。质押的资产无法在系统内产生,意味着较早参与记账的节点除了比较晚参与的节点获得更多收入以外,没有其他优势。现在看看Mixin Network如何实践这一原则。主网节点第一年需要质押10000个 xin token。质押之后就可以直接成为节点,拥有参与记账的权利。 整个过程无需投票,有钱,有网就可以。符合自由市场定义。主网节点可以获得系统预留的记账奖励,目前是所有主网节点平均分。一笔转账经过2f+1节点验证成功即有效。因此试图篡改账本需要购买其他节点或者购买更多token成为节点。XIN token 本身是固定100万总量的ERC20 token,不会转换到主网,也没有设计暂停机制,因此可以知道质押的资产是系统内无法生成的。集体主义如何记账?需要承认集体主义的代理记账才是社会的主流,正如开银行不是有钱就能干,而是首先需要审批。 现在看看DPOS如何应用集体主义原则记账: 节点需要获得投票才能参与记账,而不是质押,这意味记账权利交给了集体意志的代理人,而不是自由市场。质押的资产可以在系统内生成,而且可以增发。合谋篡改账本不需要投入金钱,只需要获得大多数代理人同意,而不是全部投票人同意。EOS一笔交易成为不可逆只需要3分钟,已经比比特币的1小时通行标准快的多了,但是他的账本长期可靠性等同于SWIFT银行间转账,因为只要代理人同意,他们可以冻结任何一个人资产,而只需要付出很小的代价。正如现在美国可以冻结任何一个银行的美元账户,欧盟可以冻结任何欧元账户。 自由主义,还是集体主义?比特币通过将记账权交给自由主义市场,实现了长期的账本安全,从而吸引更多的资产,更多的资产存储进比特币网络,也推高了比特币价格,使比特币网络更强大,这是一个不可思议但是真实存在正循环。 自由主义市场是这种正循环的源泉,同样采用自由市场记账的Mixin Network 也会实现这种正循环,价格越来越高,网络越来越强大。

June 27, 2019 · 1 min · jiezi

如何使用docker和dockercompose在EOS本地Testnet上开发

EOS区块链的开发并不是立竿见影的,因为需要一些非显而易见的组件,需要对它们进行配置和协同工作。 nodeos:块生成器守护程序。keosd:钱包守护进程,存储私钥。eosio-cpp:智能合约编译器。eosio.token:平台的参考标记。cleos:用于与EOS区块链远程交互的CLI。scatter:为本地Testnet配置的EOS钱包。 我将学到什么?如何运行和初始化EOS本地Testnet。如何编译和运行EOS智能合约。如何通过cleos进行EOS交易。要求要学习本教程,你需要使用下面的软件: Ubuntu Linux(推荐)docker/docker-compose困难程度中间教程内容Dockerfile(你需要的软件)docker-compose.yml(该软件应该如何运行)cleos,命令行EOS钱包。部署eosio.token,即EOS货币系统智能合约。Dockerfile(你需要的软件)。你可以直接在Linux操作系统上安装以下组件,但这样可以使你的开发环境更加干净,更易于维护和测试。 以下所有文件均为官方文件,并由EOSIO发布: FROM ubuntu:18.04RUN apt-get update && apt-get install -y curl libicu60 libusb-1.0-0 libcurl3-gnutlsRUN curl -LO https://github.com/EOSIO/eos/releases/download/v1.7.0/eosio_1.7.0-1-ubuntu-18.04_amd64.deb \ && dpkg -i eosio_1.7.0-1-ubuntu-18.04_amd64.debRUN curl -LO https://github.com/EOSIO/eosio.cdt/releases/download/v1.6.1/eosio.cdt_1.6.1-1_amd64.deb \ && dpkg -i eosio.cdt_1.6.1-1_amd64.debRUN curl -LO https://github.com/EOSIO/eosio.cdt/archive/v1.6.1.tar.gz && tar -xvzf v1.6.1.tar.gz --one-top-level=eosio.cdt --strip-components 1RUN cd /eosio.cdt/ && curl -LO https://github.com/EOSIO/eosio.contracts/archive/v1.6.0-rc3.tar.gz && tar -xvzf v1.6.0-rc3.tar.gz --one-top-level=eosio.contracts --strip-components 1你可以使用以下命令生成打包的镜像沙箱: docker build -t my/eos .docker-compose.yml(该软件应该如何运行)正如我所说,需要一些配置来互相讨论所需的所有部分。 default.wallet是一个预配置的钱包,带有用于测试的私钥。config.ini是Block Producer(BP)的文件,在EOS Mainnet中你不会/不能改变它。version: '3'services: nodeos: container_name: nodeos image: my/eos command: nodeos -e -p eosio --plugin eosio::producer_plugin --plugin eosio::history_plugin --plugin eosio::chain_api_plugin --plugin eosio::history_api_plugin --plugin eosio::http_plugin --http-server-address=0.0.0.0:8888 --access-control-allow-origin=* --contracts-console --http-validate-host=false --filter-on="*" stop_grace_period: 3m0s volumes: - ./:/eosio.cdt/contract - ./config.ini:/root/.local/share/eosio/nodeos/config/config.ini ports: - '8888:8888' - '9830:9876' depends_on: - keosd keosd: container_name: keosd hostname: keosd image: my/eos command: keosd --http-server-address=0.0.0.0:8901 --http-validate-host 0 --verbose-http-errors --unlock-timeout=9999999 volumes: - ./default.wallet:/root/eosio-wallet/default.wallet expose: - 8901 ports: - '8901:8901'运行在新终端中运行以下命令: ...

May 14, 2019 · 2 min · jiezi

用C在去中心化交易所OceanOne上挂单买卖任意ERC20-token

用C#在去中心化交易所OceanOne上挂单买卖任意ERC20 token 在上一课中,我们介绍了如何在OceanOne交易比特币。OceanOne支持交易任何Mixin Network上的token,包括所有的ERC20和EOS token,不需要任何手续和费用,直接挂单即可。下面介绍如何将将一个ERC20 token挂上OceanOne交易。掌握了ERC20的代币买卖之后,你就可以用同样的方法买卖任何EOS以及其他Mixin Network上的token 此处我们用一个叫做Benz的ERC20 token为例。这个token已经被充值进Mixin Network,你可以在区块链浏览器看到这个token在Mixin Network内部的总数和交易 预备知识:先将Ben币存入你的钱包,然后使用getAssets API读取它的UUID. 取得该币的UUID调用 getAssets API 会返回json数据, 如: asset_id 币的UUID.public_key 该币的当前钱包的地址.symbol 币的名称. 如: Benz.if (cmd == "aw" ) { // Console.WriteLine(mixinApi.VerifyPIN(USRCONFIG.PinCode.ToString()).ToString()); MixinApi mixinApiNewUser = GetWalletSDK(); var assets = mixinApiNewUser.ReadAssets(); string wuuid = GetWalletUUID(); Console.WriteLine("Current wallet uuid is " + wuuid); foreach (Asset asset in assets) { if (asset.symbol == "EOS") { Console.WriteLine(asset.symbol + " Public Address is: " + asset.account_name + " " + asset.account_tag + " Balance is: " + asset.balance); } else Console.WriteLine(asset.symbol + " Public Address is: " + asset.public_key + " Balance is: " + asset.balance); Console.WriteLine(); }}调用 getAssets API的完整输出如下: ...

May 9, 2019 · 3 min · jiezi

EOS源码解析 创建账号的三种方式。

第一种:创建系统账号eosio的方式。直接调用create_native_account 方法直接进行创建。并将资源设置成无限。 void create_native_account( account_name name, const authority& owner, const authority& active, bool is_privileged = false ) { //create account 直接创建账号,不会做任何资源判断,因为创建的是系统账号 db.create<account_object>([&](auto& a) { a.name = name; a.creation_date = conf.genesis.initial_timestamp; a.privileged = is_privileged; if( name == config::system_account_name ) { a.set_abi(eosio_contract_abi(abi_def())); } }); db.create<account_sequence_object>([&](auto & a) { a.name = name; }); const auto& owner_permission = authorization.create_permission(name, config::owner_name, 0, owner, conf.genesis.initial_timestamp ); const auto& active_permission = authorization.create_permission(name, config::active_name, owner_permission.id, active, conf.genesis.initial_timestamp ); //初始化账号资源,但是初始化赋值只赋了resource_limits_object的owner值,其他cpu,ram,net等资源默认是-1,也就是unlimit。 resource_limits.initialize_account(name); int64_t ram_delta = config::overhead_per_account_ram_bytes; ram_delta += 2config::billable_size_v<permission_object>; ram_delta += owner_permission.auth.get_billable_size(); ram_delta += active_permission.auth.get_billable_size(); resource_limits.add_pending_ram_usage(name, ram_delta); resource_limits.verify_account_ram_usage(name); }void resource_limits_manager::initialize_account(const account_name& account) { _db.create<resource_limits_object>([&]( resource_limits_object& bl ) { bl.owner = account; }); _db.create<resource_usage_object>([&]( resource_usage_object& bu ) { bu.owner = account; });}/** Every account that authorizes a transaction is billed for the full size of that transaction. This object* tracks the average usage of that account./struct resource_limits_object : public chainbase::object<resource_limits_object_type, resource_limits_object> { OBJECT_CTOR(resource_limits_object) id_type id; account_name owner; bool pending = false; int64_t net_weight = -1; int64_t cpu_weight = -1; int64_t ram_bytes = -1; };第二种:cleos create account 方式创建账号,调用的是eosio的默认合约,但该方式在eosio 部署了eosio.system后不可用。 因为默认合约被替换掉。eosio的默认合约是来自源码提前定义好的。具体的abi信息在:libraries/chain/eosio_contract_abi.cpp,libraries/chain/eosio_contract.cpp。跟第一种一样,同样是将资源的使用权设置为无限。 下一次再介绍eosio默认合约的形成原理,以及调用流程。/** * This method is called assuming precondition_system_newaccount succeeds a /void apply_eosio_newaccount(apply_context& context) { auto create = context.act.data_as<newaccount>(); try { context.require_authorization(create.creator);// context.require_write_lock( config::eosio_auth_scope ); auto& authorization = context.control.get_mutable_authorization_manager(); //判断公钥是否合法。 EOS_ASSERT( validate(create.owner), action_validate_exception, “Invalid owner authority”); EOS_ASSERT( validate(create.active), action_validate_exception, “Invalid active authority”); auto& db = context.db; auto name_str = name(create.name).to_string(); //判断account name的合法性 EOS_ASSERT( !create.name.empty(), action_validate_exception, “account name cannot be empty” ); EOS_ASSERT( name_str.size() <= 12, action_validate_exception, “account names can only be 12 chars long” ); // Check if the creator is privileged //只有eosio才能创建eosio.为前缀的账号。 const auto &creator = db.get<account_object, by_name>(create.creator); if( !creator.privileged ) { EOS_ASSERT( name_str.find( “eosio.” ) != 0, action_validate_exception, “only privileged accounts can have names that start with ’eosio.’” ); } //判断用户名是否存在。 auto existing_account = db.find<account_object, by_name>(create.name); EOS_ASSERT(existing_account == nullptr, account_name_exists_exception, “Cannot create account named ${name}, as that name is already taken”, (“name”, create.name)); const auto& new_account = db.create<account_object>([&](auto& a) { a.name = create.name; a.creation_date = context.control.pending_block_time(); }); db.create<account_sequence_object>([&](auto& a) { a.name = create.name; }); for( const auto& auth : { create.owner, create.active } ){ validate_authority_precondition( context, auth ); } const auto& owner_permission = authorization.create_permission( create.name, config::owner_name, 0, std::move(create.owner) ); const auto& active_permission = authorization.create_permission( create.name, config::active_name, owner_permission.id, std::move(create.active) ); context.control.get_mutable_resource_limits_manager().initialize_account(create.name); int64_t ram_delta = config::overhead_per_account_ram_bytes; ram_delta += 2config::billable_size_v<permission_object>; ram_delta += owner_permission.auth.get_billable_size(); ram_delta += active_permission.auth.get_billable_size(); context.trx_context.add_ram_usage(create.name, ram_delta);} FC_CAPTURE_AND_RETHROW( (create) ) }跟第一种一样,同样是将资源的使用权设置为无限。 下一次再介绍当没有部署eosio.system合约时,eosio默认合约的形成原理。第三种:当部署eosio.system合约时,创建账号都必须使用该合约的newaccount的action。 值得一提的是用第三种方式创建时,第二种方式的apply_eosio_newaccount也会执行。void native::newaccount( account_name creator, account_name newact / no need to parse authorities const authority& owner, const authority& active*/ ) { //当creator 不是eosio时,需要判断创建者的资源以及低于12个字符的名字是否通过拍卖。 if( creator != _self ) { auto tmp = newact >> 4; bool has_dot = false; for( uint32_t i = 0; i < 12; ++i ) { has_dot |= !(tmp & 0x1f); tmp >>= 5; } if( has_dot ) { // or is less than 12 characters auto suffix = eosio::name_suffix(newact); if( suffix == newact ) { name_bid_table bids(_self,_self); auto current = bids.find( newact ); eosio_assert( current != bids.end(), “no active bid for name” ); eosio_assert( current->high_bidder == creator, “only highest bidder can claim” ); eosio_assert( current->high_bid < 0, “auction for name is not closed yet” ); bids.erase( current ); } else { eosio_assert( creator == suffix, “only suffix may create this account” ); } } } user_resources_table userres( _self, newact); userres.emplace( newact, [&]( auto& res ) { res.owner = newact; }); //将账号资源初始化为0,不购买资源无法进行相关动作 set_resource_limits( newact, 0, 0, 0 ); } ...

March 27, 2019 · 3 min · jiezi

分享一个网友第一次开发EOS区块链总结的经验

在处理项目时,用Java Connector for EOS区块链编写:创建钱包创建帐户创建交易创建签名交易在帐户之间转移代币我遇到了各种和运行本地EOS节点需要遵循的基本步骤。这个小指南纯粹是为了帮助你启动和运行自己的EOS节点。几天的内容和图片汇编了我的阅读和理解。本指南不解释什么是区块链,这是特定的,以尽快开始使用EOS并减少麻烦。纯粹基于经验。EOS区块链概述EOSIO附带了许多程序。你将使用的主要部分以及此处涉及的部分是:nodeos(node + eos = nodeos) ,可以使用插件配置以运行节点的核心EOSIO节点守护程序。示例用法是块生产,专用API端点和本地开发。cleos(cli + eos = cleos) ,命令行界面,用于与区块链交互并管理钱包。keosd(key + eos = keosd) ,将EOSIO密钥安全存储在钱包中的组件。eosio-cpp(eosio.cdt的一部分) ,它将C ++代码编译为WASM并可以生成ABI(CDT是合约开发工具链)。这些组件之间的基本关系如下图所示。最新堆栈版本(截至本文编写日)nodeos:1.5.0cleos:1.5.0keosd:1.5.0eosio.cdt:1.4.1eosio.contracts:1.4.0安装本地节点有几种方法可以做到:1.使用Docker,快速简便。2.使用二进制文件,它也行。使用Docker安装You create 2 containers. One for ’nodeos’ and another for ‘keosd’#Pull latest docker image of EOSdocker pull eosio/eos-dev#Create local networkdocker network create eosdev#Start nodeos(Core Daemon)docker run –name nodeos -d -p 8888:8888 –network eosdev -v /tmp/eosio/work:/work -v /tmp/eosio/data:/mnt/dev/data -v /tmp/eosio/config:/mnt/dev/config eosio/eos-dev /bin/bash -c “nodeos -e -p eosio –plugin eosio::producer_plugin --plugin eosio::history_plugin –plugin eosio::chain_api_plugin --plugin eosio::history_api_plugin –plugin eosio::http_plugin -d /mnt/dev/data –config-dir /mnt/dev/config –http-server-address=0.0.0.0:8888 --access-control-allow-origin=* –contracts-console –http-validate-host=false”###### NOTES about above Command- Creating a docker container running ’nodeos’ daemon- Exposing port 8888 so that you can access the ’nodeos’ using RPC and HTTP- Mounting few directories on your local machine so that you don’t have to login into container- Few plugins which will allow this node to become a producer, expose rpc api over http, exposing command line interface to run ’nodeos’ commands#Run keosd(Wallet and Keystore)docker run -d –name keosd –network=eosdev -i eosio/eos-dev /bin/bash -c “keosd –http-server-address=0.0.0.0:9876”#Check installationdocker logs –tail 10 nodeosand you will see something like:info 2018-12-04T15:01:22.003 thread-0 producer_plugin.cpp:1494 produce_block ] Produced block 00005ce7fabcbcf8… #23783 @ 2018-12-04T15:01:22.000 signed by eosio [trxs: 0, lib: 23782, confirmed: 0]info 2018-12-04T15:01:22.507 thread-0 producer_plugin.cpp:1494 produce_block ] Produced block 00005ce84867bcbf… #23784 @ 2018-12-04T15:01:22.500 signed by eosio [trxs: 0, lib: 23783, confirmed: 0]info 2018-12-04T15:01:23.005 thread-0 producer_plugin.cpp:1494 produce_block ] Produced block 00005ce936ca4869… #23785 @ 2018-12-04T15:01:23.000 signed by eosio [trxs: 0, lib: 23784, confirmed: 0]i#Check Wallets (Open bash for keosd)docker exec -it keosd bashand once in the container, on bash, execute this:cleos –wallet-url http://127.0.0.1:9876 wallet list keysShould show empty wallets:Wallets: []#Check ’nodeos’ end points - run this out side containerscurl http://localhost:8888/v1/chain/get_info{ “server_version”:“549c96cd”, “chain_id”:“cf057bbfb72640471fd910bcb67639c22df9f92470936cddc1ade0e2f2e7dc4f”, “head_block_num”:24182, “last_irreversible_block_num”:24181, “last_irreversible_block_id”:“00005e751a1e31b15acd25ffc8725cb2c67926647edb89e726e386716afdef5d”, “head_block_id”:“00005e76fd035dbf694d2a575bb1849f436428b466fd95323e43619b73bf7b9d”, “head_block_time”:“2018-12-04T15:04:41.500”, “head_block_producer”:“eosio”, “virtual_block_cpu_limit”:200000000, “virtual_block_net_limit”:1048576000, “block_cpu_limit”:199900, “block_net_limit”:1048576, “server_version_string”:“v1.5.0-rc2”}#Alias cleos so that you can access it by simply ‘cleos’docker network inspect eosdevcheck for keosd IP address in the response of above command and execute the following:alias cleos=‘docker exec -it nodeos /opt/eosio/bin/cleos –url http://127.0.0.1:8888 –wallet-url http://172.18.0.3:9876’使用二进制文件安装 - MAC指令#Step 1: Install binariesbrew tap eosio/eosiobrew install eosio#Step 2: Setup a development directory, stick to it.mkdir contractscd contracts#Step 3: Install CDT. The EOSIO Contract Development Toolkit, CDT for shortbrew tap eosio/eosio.cdtbrew install eosio.cdt#Boot Node and Wallet #Start keosd: keosd & #Start nodeos: nodeos -e -p eosio --plugin eosio::producer_plugin –plugin eosio::chain_api_plugin –plugin eosio::http_plugin –plugin eosio::history_plugin –plugin eosio::history_api_plugin -d /Users/vijay/eos_blockchain/contracts/eosio/data --config-dir /Users/vijay/eos_blockchain/contracts/eosio/config '–access-control-allow-origin=’ –contracts-console –http-validate-host=false ‘–filter-on=’ >> nodeos.log 2>&1 & #Check installation (in current directory) tail -f nodeos.log #Check the wallet cleos wallet list #Check nodeos endpoints curl http://localhost:8888/v1/chain/get_info上述步骤之一将帮助你设置和运行本地节点。使用钱包,帐户和密钥现在你准备好在区块链上做一些事情。在EOS中,你必须拥有一个帐户才能执行任何操作,例如创建token,发送token,接收token,编写交易等。此节点将有一个名为eosio的系统用户,因此你可以使用此用户来玩eos区块链。因此,在本节中,我们将在本地节点上执行以下操作:创建一个新钱包。创建新密钥(私人+公共)。将这些钥匙导入钱包。建立新帐户。让我们运行一些命令并观察你所看到的。只需阅读所有命令的注释,即可了解它们的作用。#List existing wallets. Wallet stores keyscleos wallet list#List wallet keys if anycleos wallet list key#you should see all empty response#create wallet nowcleos wallet createCreating wallet: default"PW5JYR5u7WTk6RaJARE41qb3Wy6BJtcKCjpDAyjR2uV3CWF8nDFe7"this will create wallet with name ‘default’. Keep note of password it returns.#Create new keyscleos create key –to-consolePrivate key: 5JseP8pEsJfAEWix5U6ow77TrKu2uuBhjfobyzgYyCYAtnxnCk8Public key: EOS4tmc8ufENZNkFQaj8ZfV9UfeRLnyaCecybSgPS1U8671BNdSxD#Import the private keys in wallet cleos wallet import -n quant –private-key 5JseP8pEsJfAEWix5U6ow77TrKu2uuBhjfobyzgYyCYAtnxnCk8#### MOST IMPORTANT STEP ####Import genesis ’eosio’ account keys in the wallet so that eosio account is available for creating new accounts.Private key of eosio: 5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3在这个阶段,你已准备好带有eosio(创世纪帐户)的钱包和导入的新密钥。所以我们现在准备好做更多的操作了。我们将在下一节中执行以下操作:部署token合约,以便区块链准备好创建新的token。创建新token。将新token分配给创世帐户(eosio)。在用户之间转移token。检查余额等。#Deploy Token Contacts create an account first with the name ’eosio.token’ for the contractcleos create account <owner> <newaccountname> <pubkey1> <pubkey2>cleos create account eosio eosio.token EOS5ySgzeHp9G7TqNDGpyzaCtahAeRcTvPRPJbFey5CmySL3vKYgE EOS5ySgzeHp9G7TqNDGpyzaCtahAeRcTvPRPJbFey5CmySL3vKYgEyou would see something like this:executed transaction: 4a8b53ae6fa5e22ded33b50079e45550e39f3cb72ffa628e771ea21758844039 200 bytes 339 us # eosio <= eosio::newaccount {“creator”:“eosio”,“name”:“eosio.token”,“owner”:{“threshold”:1,“keys”:[{“key”:“EOS5ySgzeHp9G7TqNDGpy…Deploy contract now:cleos set contract eosio.token <path-to-contracts-directory>/contracts/eosio.token -p eosio.tokenyou would see something like this:Reading WAST/WASM from /opt/eosio/bin/data-dir/contracts/eosio.token/eosio.token.wasm… Using already assembled WASM… Publishing contract… executed transaction: 41677b5fd5c701ca67a153abb09f79c04085cc51a9d021436e7ee5afda1781bd 8048 bytes 1212 us # eosio <= eosio::setcode {“account”:“eosio.token”,“vmtype”:0,“vmversion”:0,“code”:“0061736d01000000017f1560037f7e7f0060057f7e… # eosio <= eosio::setabi {“account”:“eosio.token”,“abi”:“0e656f73696f3a3a6162692f312e30010c6163636f756e745f6e616d65046e616d65…#Create new Tokencleos push action eosio.token create ‘[“eosio”, “10000000000.0000 EOS”,0,0,0]’ -p eosio.tokenyou would see like this:executed transaction: 566693cba0b0d5d11d85e40cdfb095d525612c5915e17ce75d309054e1912235 120 bytes 552 us # eosio.token <= eosio.token::create {“issuer”:“eosio”,“maximum_supply”:“10000000000.0000 EOS”}#Send newly created Tokens (EOS) to genesis account (eosio)cleos push action eosio.token issue ‘[“eosio”,“1000000000.0000 EOS”, “issue”]’ -p eosioyou would see something like this:executed transaction: 73f72879d220c720fcefb16b6aaf3db0ba492bd62020853b2cd5051557d5fa87 128 bytes 677 us # eosio.token <= eosio.token::issue {“to”:“eosio”,“quantity”:“1000000000.0000 EOS”,“memo”:“issue”}#Check above transactions if they are completedcleos get transaction 73f72879d220c720fcefb16b6aaf3db0ba492bd62020853b2cd5051557d5fa87andcleos get transaction 566693cba0b0d5d11d85e40cdfb095d525612c5915e17ce75d309054e1912235you should have long JSON response. It simply means above steps are successful.#Check balance now of eosio accountcleos get currency balance eosio.token eosioyou would see:1000000000.0000 EOS你去了,现在你已经创建了token,eosio帐户有很多EOS token,他现在可以轻松地将资金发送到其他帐户。#Create a new accountcleos create account eosio user1 <public_key_of_user1> <public_key_of_user1>#Check if account is created. You should have json responsecleos get account user1#Send money to user1 accountcleos transfer eosio user1 “1000.00 EOS”#Check the balance of user1cleos get currency balance eosio.token vijay1仅此而已!分享两个EOS区块链相关的交互式在线编程实战教程:EOS入门教程,本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。深入浅出玩转EOS钱包开发,本课程以手机EOS钱包的完整开发过程为主线,深入学习EOS区块链应用开发,课程内容即涵盖账户、计算资源、智能合约、动作与交易等EOS区块链的核心概念,同时也讲解如何使用eosjs和eosjs-ecc开发包访问EOS区块链,以及如何在React前端应用中集成对EOS区块链的支持。课程内容深入浅出,非常适合前端工程师深入学习EOS区块链应用开发。汇智网原创翻译,转载请标明出处。这里是网友第一次开发EOS区块链的经验 ...

March 19, 2019 · 4 min · jiezi

DAppDiscover | 盘点2018年度十大DAPP

作者:DD君欢迎添加作者微信 btcbtc555 与他进行交流!未经授权禁止转载!2018年可以说是DApp爆发的元年,这一年出现了好几款现象级DApp。有曾经让以太坊严重拥堵的CryptoKitties(加密猫),有史上最大的资金盘游戏Fomo 3D,还有区块链房地产EOS Pixel Master(像素大师)——一个像素最高价达到了4483.87EOS(折合人民币17万多)!当然,除了资金盘游戏之外,也出现了像EOS Knights、加密英雄这样,制作精良、质量上成、高可玩性的区块链游戏。DAppDiscover团队从2000多个DApp中筛选出了2018年度十大DApp,综合考虑了它们的影响力、可玩性和游戏设计三个方面,一起来看一看吧!10. 波场虾农影响力:3.5分可玩性:3.5分游戏设计:3.0分平台 :TRON发布时间 :2018-12-14网址:https://tronshrimp.farm/波场虾农属于养殖类游戏。逻辑就是买蛋,孵蛋,生蛋,卖蛋。“蛋"可以无限孵化,但相应价格会越来越低。这是波场第一款爆款游戏,上线后一举创下波场 DAPP 日活记录,达到 3 万 DAU。但此款游戏严重抄袭游戏以太虾农,二者连UI都相差无几。9.PoWH 3D影响力:3.5分可玩性:3.5分游戏设计:3.5分平台 :ETH发布时间 :2018-02-26网址 :https://powh.io/PoWH 3D同样属于资金盘类游戏。玩这个游戏须先购买虚拟代币,购买代币需要交10%手续费。持有虚拟代币后,会收到分红,这个分红比例则根据游戏每日产生的收益,按照你持有代币的量分配。该游戏利用新玩家的钱来向老玩家支付利息和短期回报,以制造赚钱的假象,进而骗取更多的玩家入场,属于典型的庞氏骗局游戏。8. CryptoCountries影响力:3.5分可玩性:4.5分游戏设计:3.5分平台 :ETH发布时间 :2018-02-01网址 :https://cryptocountries.io/《CryptoCountries》是一款基于以太坊的卡牌类游戏。游戏主要玩法就是将每个国家在区块链上做成类似虚拟代币一样的token,玩家通过购买这些token来“征服”这个国家。“征服”后,你的名字将写在国家的token上。这款游戏的本质就是击鼓传花。该游戏中玩家拥有一个国家的所有权后,如若其他玩家要想获得,需支付更高的价格。由于宣传噱头到位,2018年春节前后的一周时间里,它创造了4.5万ETH的交易流水。7. BetDice影响力:4.0分可玩性:4.5分游戏设计:3.5分平台 :EOS发布时间 :2018-09-21网址:https://betdice.one/BetDice是一款掷骰子游戏,玩法简单,只要玩家投出小于其设定的数字就获胜。前期的代币空投活动,以及后续的抽奖活动,使BetDice吸引了大量的用户,上线三周后累积成交量就超过3400万EOS。6. 以太水浒影响力:4.0分可玩性:4.5分游戏设计:4.0分平台 :ETH发布时间 :2018-02-17网址 :http://cryptohero.pro/《以太水浒》也是一款由区链块技术打造的水浒题材的策略卡牌类手机游戏,游戏中,每张卡牌都代表一位英雄,玩家可以进行自由的买卖,获得以太币的奖励。《以太水浒》是中国第一个国产DApp。该款游戏发行时刚好卡在击鼓传花类游戏高峰期,外加上打着中国第一旗号,它着实火了一把。尽管现在看这款游戏的方方面面做的都很差,但火爆时卡牌人物宋江曾被炒到50ETH+。5. EOS Pixel Master影响力:4.0分可玩性:4.5分游戏设计:4.5分平台 :EOS发布时间 :2018-09-23网址:https://pixelmaster.io/EOS Pixel Master是EOS ASIA制作的一款EOS链上画板。主要就是在一块1000x1000像素的画布上作画,再使用 EOS 去购买相应位置上的像素。此款游戏同属于现象级DApp,上线9天之内吸金80万美元,并获BM点赞。4. 加密英雄影响力:4.5分可玩性:4.5分游戏设计:4.5分平台 :ETH发布时间 :2018-09-21网址 :https://www.mycryptoheroes.ne…加密英雄是由日本游戏公司double jump制作的,它是一款RPG游戏。此游戏使用了历史或者传说中的英雄人物作为原型。该游戏正式推出后,几天内就冲入ETH游戏榜单的第一名。游戏整体呈像素风格,UI设计和用户体验都还可以,在游戏DAPPs中的表现也可圈可点。3.CryptoKitties影响力:5分可玩性:4.5分游戏设计:4.5分平台 : ETH发布时间 :2017-11-23网址 :https://www.cryptokitties.co/《CryptoKitties》是一款由Axiom Zen开发的区块链宠物养成游戏。在游戏中,玩家使用以太币进行电子猫的购买、喂食、照料与交配等,但其最为核心是玩法是将以太坊区块链中的电子猫进行出售。该款游戏是以太坊上第一个现象级的区块链游戏,也是至今为止生命周期最长的游戏类DApp,创造了单日14000+日活跃地址记录(2017年12月09日),一度造成以太坊交易堵塞。2.Fomo 3D影响力:5分可玩性:4.5分游戏设计:5分平台 :ETH发布时间 :2018-07-05网址 :https://exitscam.meFomo 3D是一款典型的资金盘游戏。游戏玩法简单:只要你是最后一个出价的人,并且这个价格维持 24 小时,那么奖池里的所有以太坊都给你。它包括了:闪拍系统、分红系统、战队系统、排行榜系统和邀请系统,加强了游戏的可玩性。此游戏由于有最终Key购买者独占奖池的诱惑,玩家会主动向奖池持续注入ETH。第一轮游戏结束时,奖池金额高达10469.66ETH,轰动整个DApp圈。同时也是由于此款游戏的成功,后续引出了近百个仿品。1.EOS Knight影响力:5分可玩性:5分游戏设计:5分平台 :EOS发布时间 :2018-07-08网址 :http://eosknights.io/EOS Knights是一款由韩国BADA工作室开发的RPG游戏。玩家首先需要用EOS在游戏中购买英雄,然后通过打怪让英雄升级。玩家在打怪的过程中,获得系统奖励的宝物。玩家可以通过出售宝物,赚取EOS。该游戏从去年7月份上线到现在,日活交易量等都保持良性发展态势,是EOS游戏中的一股清流。小结复盘2018,我们不难发现去年火爆的DApp基本都属于博彩类,从狂热到崩塌,“戏里戏外"间人性的贪婪演绎的淋漓尽致。但狂热过后,伴随着的确是理性的回归。目前已有越来越多的正规游戏厂商开始关注DApp,准备着手进军这一领域。DappDiscover团队也由衷希望2019DApp领域呈现新气象。所有的游戏种类,该佩奇的都“佩奇”,而非仅仅是菠菜类的天下。你有哪些感兴趣的DApp?欢迎留言回复下一次讨论的,也许就是它。

February 12, 2019 · 1 min · jiezi

使用智能合约实现自动分账

自动分账是很多平台都会用到的支付功能。很多互联网内容售卖平台都会跟内容提供者分账。比如:Apple 的 App Store 跟 App 开发者三七分成。很多平台都使用了支付宝、微信支付作为支付手段,但是要同时实现给内容提供者分账,却是一件不太容易的事。使用 FIBOS 智能合约可以很容易实现这个需求。文中代码已在 GitHub 上开源。https://github.com/fengluo/fi…设计思路在 FIBOS 转账是通过 token 合约的extransfer方法来实现的。extransfer方法在执行的时候会给转账方账户和入账方账户发送通知。所以用户给平台方账户转账的时候,平台账户就会收到通知。所以整体业务逻辑如下: quantity: 10 FO memo: 内容提供者账户 quantity: 8 FO用户账户 ——————-> 平台账户 —————-> 内容提供者账户 extransfer 2/8 分成 extransfer用户给平台方账户转账,memo 中填写内容提供者的账户名。平台方的账户合约监听 extransfer 方法的通知,然后做出分账计算,给对应内容提供者的账户转账对应金额。整体逻辑很简单,整个合约代码逻辑差不多用20行就可以写完。编写合约FIBOS 的智能合约分为 ABI 文件和 JS 合约两部分。ABI 相当于合约接口,JS 合约则是功能实现。本案例目前没有接口设计需求,不过 ABI 文件还是合约不可缺少的部分。所以我们简单创建一下就好。我们先创建一个 contracts 文件夹,合约文件都会放在这里。然后在此文件夹下,创建 subaccount.abi 文件,内容为:{ “version”: “eosio::abi/1.0”}JS 合约部分也没有太复杂。在 contracts 文件夹下创建 subaccount.js 文件,代码为:exports.on_extransfer = (from, to, quantity, memo) => { // 需要在开头做一些判断 if (to === action.receiver && action.is_account(memo)) { const num = parseInt(quantity.quantity.split(’ ‘)[0]) // 假设我们约定平台方跟内容提供者是2/8分成。 const subnum = (num * 0.8).toFixed(4); trans.send_inline(’eosio.token’, ’extransfer’, { from: to, to: memo, quantity: { quantity: ${subnum} ${quantity.quantity.split(' ')[1]}, contract: quantity.contract }, memo: ‘sub account’ }, [ { // 需要提供合约账户的 active 权限 actor: action.receiver, permission: ‘active’ } ]); }}合约代码开头我们需要做一些验证。收款方的账户为合约账户,否则因为下面代码执行给内容提供者转账时,因为转帐方也是合约账号会再次收到通知,造成无限递归,超出最大 send_inline 层数而报错。我们用 memo 参数来放内容提供者的账户,所以我们需要对此参数校验一下该账户是否存在防止打错。合约代码中我们使用 send_inline 调用 eosio.token 合约来执行转帐操作。转帐操作需要对应账户的 active 权限才能执行。为了解决权限滥用问题,FIBOS 定义了一个特殊权限 eosio.code。我们需要在平台合约账户中配置权限,在 active 权限下添加该合约账户的 eosio.code 授权。具体的配置操作会在下面说明。在 FIBOS TestNet 上注册账号为方便测试,我们在测试网 http://testnet.fibos.fo 上注册三个账户。用户账号 helloworld11内容提供者账号 helloworld22平台合约账号 helloworld33我们需要记录这三个账号的账户名以及公私钥。以便下面的开发使用。创建一个统一的配置文件来记录这些数据:const config = { // 平台合约账户的客户端配置 client: { chainId: ‘68cee14f598d88d340b50940b6ddfba28c444b46cd5f33201ace82c78896793a’, httpEndpoint: ‘http://testnet.fibos.fo’, keyProvider: ‘PRIVATE_KEY_OF_helloworld33’ }, // 用户账户的客户端配置 callClient:{ chainId: ‘68cee14f598d88d340b50940b6ddfba28c444b46cd5f33201ace82c78896793a’, httpEndpoint: ‘http://testnet.fibos.fo’, keyProvider: ‘PRIVATE_KEY_OF_helloworld11’ }, // 平台合约账户信息 contractAccount: { name: ‘helloworld33’, publicKey: ‘PUBLIC_KEY_OF_helloworld33’, privateKey: ‘PRIVATE_KEY_OF_helloworld33’ }, // 用户账户信息 account1: { name: ‘helloworld11’, publicKey: ‘PUBLIC_KEY_OF_helloworld11’, privateKey: ‘PRIVATE_KEY_OF_helloworld11’ }, // 内容提供者账户信息 account2: { name: ‘helloworld22’, publicKey: ‘PUBLIC_KEY_OF_helloworld22’, privateKey: ‘PRIVATE_KEY_OF_helloworld22’ }}module.exports = config配置权限在合约代码中,我们调用了 trans.send_inline 函数调用合约 eosio.token 来实现转帐操作,但是转帐操作是需要账户的 active 权限。所以我们需要更新一下合约账户的权限,需要添加调用者的 eosio.code 授权到它的 active 权限。这个调用者自然也是这个合约账户。const FIBOS = require(‘fibos.js’);const config = require(’./config’);const fibosClient = FIBOS(config.client);let ctx = fibosClient.contractSync(’eosio’);var r = ctx.updateauthSync({ account: config.contractAccount.name, permission: ‘active’, parent: ‘owner’, auth: { threshold: 1, keys: [{ key: config.contractAccount.publicKey, weight: 1 }], accounts: [{ permission: { // 将调用者账号的 eosio.code 授权添加到它的 active 权限下。 actor: config.contractAccount.name, permission: ’eosio.code’ }, weight: 1 }] }},{ authorization: ${config.contractAccount.name}@owner //更改账户权限需要使用 owner 权限});console.log(r);部署合约const FIBOS = require(‘fibos.js’);const config = require(’./config’);const fibosClient = FIBOS(config.client);const fs = require(‘fs’);// setcodeconst jsCode = fs.readTextFile(${__dirname}/contracts/subaccount.js);fibosClient.setcodeSync(config.contractAccount.name, 0, 0, fibosClient.compileCode(jsCode));// getcodeconst code = fibosClient.getCodeSync(config.contractAccount.name, true);console.log(‘code:’, code);// setabiconst abi = JSON.parse(fs.readTextFile(${__dirname}/contracts/subaccount.abi));fibosClient.setabiSync(config.contractAccount.name, abi);转账测试我们先来写一个脚本 account.js 来查看三个账户的余额。const FIBOS = require(‘fibos.js’);const config = require(’./config’);const fibosClient = FIBOS(config.callClient);const account1 = fibosClient.getTableRowsSync(true, ’eosio.token’, config.account1.name, ‘accounts’);console.log(config.account1.name);console.log(account1);const account2 = fibosClient.getTableRowsSync(true, ’eosio.token’, config.account2.name, ‘accounts’);console.log(config.account2.name);console.log(account2);const contractAccount = fibosClient.getTableRowsSync(true, ’eosio.token’, config.contractAccount.name, ‘accounts’);console.log(config.contractAccount.name);console.log(contractAccount);执行 fibos account.js 来查看三个账户信息。 目前我们的账户还没有 FO,所以大致情况是这样的:用户账户:helloworld11 金额:0.0000 FO内容提供者账户:helloworld22 金额:0.0000 FO平台合约账户:helloworld33 金额:0.0000 FO测试网会自动给每个账户发放10 EOS 的通证用以测试使用。账户中还并没有 FO 通证。所以我们再来写一个兑换脚本,用1 EOS 换一点 FO 通证。const FIBOS = require(‘fibos.js’);const config = require(’./config’);const fibosClient = FIBOS(config.callClient);let ctx = fibosClient.contractSync(’eosio.token’);const r = ctx.exchangeSync( config.account1.name, ‘1.0000 EOS@eosio’, ‘0.0000 FO@eosio’, ’exchange FO to EOS’, { authorization: config.account1.name });console.log(r)再次执行 fibos account.js 来查看账户信息。目前我们的账户金额大致是这样的:用户账户:helloworld11 金额:146.4245 FO内容提供者账户:helloworld22 金额:0.0000 FO平台合约账户:helloworld33 金额:0.0000 FO下面写个脚本 transfer.js 来执行转帐操作。const FIBOS = require(‘fibos.js’);const config = require(’./config’);const fibosClient = FIBOS(config.callClient);let ctx = fibosClient.contractSync(’eosio.token’);const r = ctx.extransferSync( config.account1.name, // 用户账户 config.contractAccount.name, // 平台合约账户 ‘10.0000 FO@eosio’, // 转帐金额 config.account2.name, // 附言填写内容提供者的账户名,平台合约会给它分账 { authorization: config.account1.name //提供用户账户的授权 })console.log(r)我们要从用户账户 account1 给平台合约账户 account3 转帐 10 FO。memo 参数为要分成的内容提供者账户 account2。根据合约中定的2/8分成,平台合约账户 account3 将会分得2 FO,而内容提供者账户 account2 将会获得8 FO。使用命令 fibos transfer.js 执行该脚本完成转帐操作。下面我们再来看一下目前三个账户情况。执行命令 fibos account.js。三个账户金额大致如下。用户账户:helloworld11 金额:136.4245 FO内容提供者账户:helloworld22 金额:8.0000 FO平台合约账户:helloworld33 金额:2.0000 FO结果显示,分账账户和平台合约账户如预期那样获得8 FO 和2 FO。综上,我们成功使用了智能合约实现了自动分账。平台方还可以继续根据自己业务需要定制自己的合约。文中的代码请参考:https://github.com/fengluo/fi… ...

January 30, 2019 · 3 min · jiezi

一文搞懂区块链跨链技术

区块链的跨链技术是什么?自比特币10年前诞生以来,数以千计的区块链公链被开发出来,基于各种公链的加密货币数量更呈现井喷式增长。客观来看,各条公链都具有自己独特的优势和特征,以 EOS 为代表的公链更是提出了“侧链”的概念。基于“侧链”的概念,EOS 打出了百万级 TPS(系统吞吐量) 的口号。要知道比特币的 TPS 最高值仅有 7,也就是说比特币每秒钟仅支持 7 笔交易。作为区块链 2.0 代表的以太坊的 TPS 也不过才 30~40。而 EOS 号称可以达到百万级 TPS 的技术基础正是“侧链跨链”。跨链技术可以被理解为一种协议,解决两个或多个不同链上的资产以及功能状态不能互相传递、转移、交换的问题。也就是说,跨链技术能够增加区块链的可拓展性,能够从根本上解决不同公链/侧链之间交易困难产生的”数据孤岛“问题。跨链技术的难点跨链技术从 Blockstream 提出侧链概念以来,一直是区块链技术的重点攻关方向。目前并没有被普遍认可的跨链机制,原因在于各个公链之间的底层技术实现差异巨大给跨链技术带来了不小的障碍。跨链需要解决的几个难点问题:保证跨链信息真实可信原链上的交易信息对于另一条链来说是一个外部信息,如何保证这个外部信息进入另一条链时是正确的,是整个跨链机制的重要环节。如果要考虑到使用 POW 机制的区块链上没有终局状态(始终存在分叉的情况,只是随着确认块的增加,概率逐渐变小),这个问题的复杂度会更高。跨链交易要确保原链上的 Token 总量不会因为跨链而减少或增多跨链技术很重要的一个应用方向就是数字资产的跨链转移,如何保证不同链上的数字资产能够安全地从一条链转移到其他链,又可以从其他区块链安全地返回主链是亟待解决的问题之一。对于数字资产的跨链转移来说,原链上 Token 总量减少的后果是当 Token 需要跨回原链时,原链无法产生新的 Token ,也就是只能单向跨链。原链 Token 增多是名义上的增多,实际上是本来已经跨链至另一个账本的 Token 在原链上被双重支付了,这种情况违背了精确记账的原则,是在任何时候都无法接受的。因此当 Token 跨出原链时,原链上的 Token 必然需要进入“锁定”的状态,当 Token 跨回原链时,这些 Token 需要被解锁。如何通过去中心化的管理机制完成“锁定”、“解锁“的过程就成为了跨链的关键。保证整个跨链交易的原子性交易的原子性,简单来说是指交易处理的某个环节停止,整个交易能够撤销,而不会存在部分成功,部分失败的情况,无法保证原子性会造成双重支付。在跨链技术中保证原子性的难点在于,跨链双方是两条独立的链,可能具有不同的共识机制、数据结构、交易处理逻辑等等,造成交易最终没有被执行的原因也千差万别。现有的跨链技术方案目前主流的区块链跨链技术有公证人机制(Notary schemes)、侧链/中继(Sidechains/relays)、哈希锁定(Hash-locking)。公证人机制公证人技术的代表就是瑞波 Interledger 协议。2012年,瑞波实验室提出 Interledger 协议,旨在连接不同账本并实现它们之间的协同。Interledger 协议适用于所有记账系统、能够包容所有记账系统的差异性,该协议的目标是要打造全球统一支付标准,创建统一的网络金融传输的协议。Interledger 协议使两个不同的记账系统可以通过第三方“连接器”或“验证器”互相自由地传输通证。记账系统无需信任“连接器”,因为该协议采用密码算法用连接器为这两个记账系统创建资金托管,当所有参与方对交易达成共识时,便可相互交易。侧链侧链是以锚定某种原链上的通证为基础的新型区块链,正如美金锚定到黄金。侧链是连接各种链,其它区块链则可以独立存在。侧链技术的代表是 BTC Relay。它被认为是区块链上的第一个侧链。BTC Relay 把以太坊网络与比特币网络通过使用以太坊的智能合约连接起来,可以使用户在以太坊上验证比特币交易。它通过以太坊智能合约创建一种小型版本的比特币区块链,但智能合约需要获取比特币网络数据,因此实现去中心化比较困难。BTC Relay 进行了跨区块链通信的有意义的尝试,打开了不同区块链交流的通道。中继技术中继技术的代表是 Polkadot。Polkadot 是由原以太坊主要核心开发者推出的公有链。它主要解决当今两大难题:即时拓展性和可扩展性。Polkadot 计划将私有链/联盟链融入到公有链的共识网络中,同时又能保有私有链/联盟链的原有的数据隐私和许可使用的特性。它可以将多个区块链互相连接。Polkadot的提出者 Gavin Wood 希望用一条中继链(Relay-chain)来实现其他所有链的交易的验证工作, 再通过平行链的创建实现与原链的交易与通信。具体来说,现在想在链 A 和链 B 间进行跨链转账,他们的中继链为链 C。链 A 先将数据发送到中继链 C 上,然后在中继链 C 上进行数据校验。校验完成后,将一份成功的凭证发送给链 A,同时向链 B 发送数据,链 B 接收数据后,向中继链 C 发送接收凭证。在链 B 操作执行成功后,会向中继链 C 发送成功凭证。哈希锁定技术哈希锁定技术的代表是闪电网络。闪电网络底层运用了 HTLC 技术和 RSMC 技术,构建了一个个链下支付通道。这些通道合在一起成为一个网络。交易双方的数目比较小的微支付可以通过一系列的链下协议完成,从而拓展比特币的性能。什么是 HTLC 哈希时间锁技术?举个例子。A 与 B 达成这样一个协议:协议将锁定 A 的1个比特币,在 T 时刻到来之前,如果 B 能够告诉 A 一个正确的“暗号” R,使得 R 的哈希值等于约定的值(R),B 就能获得者一个比特币。如果 B 在 T 时刻到来时不能提供正确的“暗号” R,那么这一个比特币自动解锁,回归 A 所有。“不需要记录在区块链上”的闪电网络还应用了 RSMC(可撤销的顺序成熟度协约)技术。具体来看,假设 A 与 B 之间有一个支付通道,二人共同存入一定资金,必须当二人都签名时才能动用这些资金。每次交易时,都要共同确认资金分配,并达成分配合约。当新的分配合约生效后,旧的分配合约失效。一旦有人,比如 A 仍然使用旧的合约来动用资金,作为惩罚这笔钱必须退还给 B 作为补偿。FIBOS 的跨链思考哈希锁定作为 FIBOS 跨链技术的选型并不理想。一来哈希锁定无法保证数据来源的可信度;此外,它还需要用户在一定时间窗口完成操作,用户本身也成为了跨链的一部分,提升了用户使用门槛。公证人机制天然比较契合 FIBOS 的生态,因为 FIBOS 中 BP 节点(Block Producer)恰好可以作为公证人。但这也带来了一定的问题,首先,BP 节点由投票产生,其变动速度较快,公证人列表需要不断的更新,需要考虑如何去中心化的同步公证人列表、以及公证人列表和 FIBOS BP 不一致所带来的数据同步问题;其次,BP 节点的可信度也存在问题,因为 BP 是由 FIBOS 选出,其公信力不能影响到其他链,这会使得跨链数据的真实信被质疑;最后,公证人机制本身存在数据重复发送的问题,降低了效率。同时,得到的数据依靠“多签”机制来判断能否执行,不能在数学层面上验证,这也会产生风险。侧链方案有一定的可取性。由于其区块状态同步在合约内进行,所以会产生不必要的 CPU,RAM 等资源消耗。同时带来的问题是,由于 FIBOS 出块速度较快(0.5s),在 FIBOS 侧链进行多块的状态同步,容易产生超时问题。使用侧链来解决数据的可信度是一个很好的方案,可是不应该将其放在合约内进行。中继方案看起来更为可取,因为中继链的存在,不会因同步状态消耗额外资源在源链上。同时,异构链的数据结构不同问题,可以用在中继链内进行数据转换解决。这使得中继方案不仅比较经济,而且能在异构链之间进行转账。唯一的问题在于锁定资产账户由谁来控制,以及状态和数据同步由谁进行,这一点在上述的中继技术方案里并没有给出答案。对于 FIBOS 生态来说,解决跨链问题是一个战略性的挑战,尤其在谈到和 EOS 之间的跨链转账问题时,跨链技术是必须要攻克的难关之一。对此,融合公证人机制和中继的方案有着较高的可行性。资产锁定账号由公证人共同掌握,公证人同时负责区块状态的初始化和给出一个同步地址。当出现跨链转账操作时,首先由见证人执行多签对跨链资产进行转出,然后进入中继链,进行数据验证。验证成功后,再由多签操作转入目标链。这使得公证人机制能够在数学层面上被验证,同时使得中继链的数据来源较为可信。区块链从技术上来说是P2P网络、加密技术和分布式账本,从经济上来说,它是价值网络。而目前,由于不同链之间通信壁垒的存在,导致了区块链的价值网络呈割裂的状态。区块链作为价值网络的基础设施部分,不应该只局限于和止步于一个个“价值孤岛”,更不能仅仅将价值圈定于一个个小的生态中。我们需要跨链技术,需要将不同链之间进行连接和拓展,构建价值网络的高速公路。随着区块链技术的高效迭代和创新,我们相信跨链技术终将成熟,区块链价值网络的高速公路也终将会把一个个“孤岛”连接起来。 ...

January 28, 2019 · 1 min · jiezi

高晓松:区块链也可以有诗与远方

2019年1月3日,高晓松的《晓说》在朋友圈刷屏了。这次高晓松没有谈风花雪月、诗与远方,而是在其母校清华大学的教室里,跟学弟学妹们深入浅出地聊起了区块链在文娱产业的革命。在传统模式下,文化作品从产出到走向市场要经历许多环节,过程十分繁琐。优秀的艺人都是稀缺资源,很多已经被一些大型公司签约了。当然经纪公司同时也会去发掘新的艺人,通过各种方式打榜推广包装成 IP。制作公司与艺人签合同后,要花费大量资金成本制作出优秀文娱作品,然后通过发行公司将文化产品投放到市场。发行公司对接各种渠道和发行终端,比如说唱片销售方QQ音乐,爱奇艺,或者是各大电影院。发行方与各种媒体进行议价,讨论如何分成,这又要花费大量的时间和精力,谈成后,文娱产品才会流入市场。如果使用区块链技术则可以降低使用版权的门槛。消费者通过这些终端购买作品。这其中的环节十分复杂,很容易被寡头垄断。在国外发行唱片大多会被 Applemusic 垄断,导致艺人丧失议价权。有些公司为了避免这种情况,会把签约艺人,制作发行,终端销售合为一体,如netflix——网飞,还有迪士尼,都在尝试自己产出作品并且在自己的终端播放。我们来分析一下传目前中文娱产业的一些弊端。文娱产业里的劣币驱逐良币首先,每个内容创作者都有其自身的独立性和局限性,无法批量化流水线生产。然而现有商业模式下的平均思维导致艺人难以释放自己的创作潜力,形成了互弱环境——个体与个体之间互相影响导致效率低下,高效者反而会被逆向淘汰。内容同质化现象严重另外一个则是内容消费中的价格均等,追求整体(传统技术和模式的限制,无法做到针对性投放和生产)以求降低制作和分发难度,则无法针对性的获取差异化收入,也无法满足绝大部分需求——这是网飞类平台出现的最重要原因。内容分发非差异化,高费低效。粉丝与艺人沟通非常困难这些问题,除了技术限制、成本限制,也包括了平台和渠道限制。传统模式里都是一大对众小。无论是内容生产、商业服务、信息沟通等等,都必然是一个掌握了单(巨头)对单(个体)绝对优势局面,这会让沟通失衡,让矛盾和问题不会即时反馈(来源纷杂、获取成本高、心理上的轻视),只会积压然后雪崩。这对于巨头和群体都是双输,我们应当随着技术进展而尝试去解决这种情况。要么让巨头群体化,其单个群体对于个体的优势不会那么大;要么让群体的力量能够被整合,就有了对巨头的压制优势。区块链为文化产业带来新思路区块链可以将同一生产内容整个环节的所有应用和消费都溯源归集,给予小众群体、大众群体的回报和激励都符合其实际状态。区块链对于版权溯源,完全可以做到收益可归集、分发可控。内容分发平台可能会变成类似滴滴的平台,具体的每一次内容消费,其收益都会被直接的反应到版权源。而在这一过程中,平台可以根据使用量等确定自身的话语权,来和不同的内容生产者确定不同的利润分成。而对于消费者而言,只需要为具体的消费付出相对应的价格,无需承担过多的不必要成本,就像预存制一样的消费。价值 TOKEN 化,艺人利益得到保证高晓松在谈到区块链时,也赞成艺人发行 Token 来跳过娱乐公司。首先艺人发行自己的通证,然后通过通证融资来制作自己的娱乐或周边产品,粉丝通过通证来兑换(购买)娱乐,艺人再把娱乐收入的20%分红给粉丝,形成良性循环。1.艺人将作品上链。在创作早期,IP 尚未建立时艺人通过众筹模式制作文娱作品,这可以参考一些优秀的众筹网站,如国外的 kickstar,国内的“点名时间”,京东金融等。很多一些不错的小众作品都是得益于这样的平台才能出现,但是,粉丝在这种模式下得到的收益是很有限的,如果把这种模式放到链上,比如像高晓松说的歌手把收益的20%分给粉丝,这样会形成更好的良性循环。2.艺人通过区块链自动实现作品的推广和管理。作品上链后会获得充足资源和关注、流量,支持者获得其预期收益回报。这就可以建立自有的经济体系,包括支持者回馈、互动参与激励等。在有了一定的粉丝基础后,艺人允许用户通过投资享受内容或收益回报,或者通过建立荣誉机制等,增强用户黏度和忠诚度,培养和归集具体的用户群体。3.艺人通过区块链获得收益并进行商务合作。娱乐所有生产、分发、流通、消费环节数据都由链上保存,艺人可以直观、清楚的获取所有应当获得的回报情况,并且可以根据情况,提前对个人、平台、商用等不同场景设定费率,继而针对性的设置不同费率实现不同目的(回馈粉丝、促成合作等)。这样就可以形成价值在各个环节自由流通。FIBOS 在价值 TOKEN 化中可以提供的技术支持。在发行通证方面, FIBOS 支持传统通证和基于 Bancor 协议的智能通证的发行,大大降低了发行的门槛。只需要艺人确定好经济模型,设置几个参数就能实现一键发币。在融资方面, FIBOS 可以实现跨链融资, FIBOS 映射了 EOS 和以太坊的资产,包括 EOS 和 稳定币FOD,此外还有 FIBOS 自己发行的通证 FO。粉丝拥有多重身份高晓松认为粉丝可以通过以下三种方式获得通证:1.兑换转账(法币购买);2.协助分享推广挖矿;3.艺人分红或发糖果获得。在各个环节中价值token化,大大降低了粉丝参与门槛,这样粉丝不单纯是传统意义上的粉丝,也会是投资机构,和一些社会群体。1.粉丝是艺人的早期投资人。粉丝购买艺人发行的通证,支持艺人的创作。2.粉丝是中期的推广者。粉丝也可以通过向他人推荐作品获得通证。区块链可以将很弱的价值衡量出来,同样为爱豆宣传的人,带来的新粉数量不一样,获得的通证价值也是可以区分的。比如说甲安利并带来了39个新粉,乙只有42个,那么在传统模式下这是无法区分的。但是区块链可以做到把非常弱的价值(衡量出来),因为Token就是联系整个区块链下面的价值交换的一个介质,这个介质就可能叫加密介质,可以细分到无数个细小领域。比如说你39个人,他42个人,你可能获得了0.39个Token,他获得是0.42个Token,这样的模式会更容易调动大家宣传的积极性。3.粉丝是终端消费者。粉丝通过购买的通证或者是推广而获得的通证在链上兑换艺人的作品。 IP 周边消费品,包括书籍、道具、手办、电子版音视频等等产物,都可以通过兑换获取。4.粉丝是后期的受益者。艺人和作品的成功会带来通证的价值提升,粉丝在早期购买的通证价格较低,通证升值后粉丝可以用来兑换其他内容消费品或持有分红。不同 IP、内容消费品产出源之间可以开放兑换系统,增加用户联系和绑定。通过区块链技术艺人可以更加贴合粉丝,创造出更高效的内容推荐和特色化的消费产品与服务体验。区块链技术打造文娱圈的健康生态通过区块链我们可以将各环节的价值 Token 化,让版权在上下游之间自由流动,大家都能参与进来。利用Token,区块链可以做到分散版权确权,可以做到把非常弱的价值衡量出来。 Token 将会从底层可以改变整个产业链,未来将会有更多创业机会。可以想见,如果未来娱乐交易依托于区块链平台,盗版侵权将无处安生。音乐人也可以跨过出版商和发行商,自主管理作品,与粉丝“零距离”接触,形成良好的文化圈生态。

January 24, 2019 · 1 min · jiezi

使用快照启动 FIBOS、EOS 节点

为什么使用快照1. 快速同步节点EOS 的日志文件已经达到了 160G,同步一个 EOS 全节点大约需要耗时 10-15 天的时间,时间成本非常高。作为一个普通 Dapp 开发者,我们并不需要之前的区块数据,所以完全不需要浪费大把时间去同步一个 EOS 全节点。通过快照同步的方式能够很好的满足我们的需求,使用最新快照启动的节点,能够在 34 分钟内完成节点同步达到主网高度,时间成本大大降低。2. 节省服务器资源 快照启动的节点,区块日志 block.log 内只会保存节点启动之后的区块数据,占用的磁盘空间更小。对比全节点和快照方式启动的节点两种方式同步 EOS 主网的结果来看,可以得出的结论是使用快照启动的节点在 CPU 和 RAM 的使用上都要远远小于全节点。这就意味着在一定程度上使用快照同步的节点能够很大程度上的降低我们的服务器成本。3. 不停机数据备份传统的区块数据备份步骤:停止同步中的节点使用压缩工具将区块数据压缩重新启动节点快照备份步骤:访问对应的接口: /v1/producer/create_snapshot,节点开始数据备份,备份结束后继续同步,无需停掉正在运行的节点。通过上面的对比可以看出,使用快照方式启动的节点,在数据备份上将更加简单便捷。快照实现的原理1. 使用快照启动相应的源码地址: https://github.com/EOSIO/eos/…,截取部分代码:auto infile = std::ifstream(my->snapshot_path->generic_string(), (std::ios::in | std::ios::binary));auto reader = std::make_shared<istream_snapshot_reader>(infile);reader->validate();reader->read_section<genesis_state>([this]( auto &section ){ section.read_row(my->chain_config->genesis); });infile.close();从源码中可以看出当启动添加参数:snapshot时,会以快照中的数据启动。2. 实现快照备份进行快照备份时,服务器资源使用情况稳定。但正在备份中的节点服务将暂时不可用,待数据备份结束后将恢复。所以推荐备份节点和业务节点独立开。相应的源码如下: https://github.com/EOSIO/eos/...producer_plugin::snapshot_information producer_plugin::create_snapshot() const { chain::controller& chain = my->chain_plug->chain(); auto reschedule = fc::make_scoped_exit(this{ my->schedule_production_loop(); }); if (chain.pending_block_state()) { // abort the pending block chain.abort_block(); } else { reschedule.cancel(); } auto head_id = chain.head_block_id(); std::string snapshot_path = (my->_snapshots_dir / fc::format_string(“snapshot-${id}.bin”, fc::mutable_variant_object()(“id”, head_id))).generic_string(); EOS_ASSERT( !fc::is_regular_file(snapshot_path), snapshot_exists_exception, “snapshot named ${name} already exists”, (“name”, snapshot_path)); auto snap_out = std::ofstream(snapshot_path, (std::ios::out | std::ios::binary)); auto writer = std::make_shared<ostream_snapshot_writer>(snap_out); chain.write_snapshot(writer); writer->finalize(); snap_out.flush(); snap_out.close(); return {head_id, snapshot_path};}从源码中可以看出,当进行快照备份时,会将备份数据写到我们设置的路径下,快照的文件名为当前区块的hash。下面我们将详细介绍在 FIBOS、EOS 上如何通过快照启动启动 FIBOS 节点注意: FIBOS 版本: v1.4.0+创建快照配置快照目录快照生成位置 config.data_dir 为根目录,可以配置为:config.data_dir = “./blockData/data"fibos.load(“producer”, {“snapshots-dir”: “snapshots”});根据配置,快照生成的位置为:./blockData/data/snapshots载入插件fibos.load(“producer_api”);注意: 开启该插件后,请确保你的节点放置在内网安全。完整配置文件可参考:const fibos = require(‘fibos’);fibos.config_dir = “./blockData/data"fibos.data_dir = “./blockData/data”;fibos.load(“http”, { “http-server-address”: “0.0.0.0:8870”, “access-control-allow-origin”: “*”, “http-validate-host”: false, “verbose-http-errors”: true});fibos.load(“net”, { “p2p-peer-address”: [], “max-clients”: 100, “p2p-listen-endpoint”: “0.0.0.0:9876”});fibos.load(“producer”, { “snapshots-dir”: “snapshots”});fibos.load(“producer_api”);fibos.load(“chain”, { “contracts-console”: true, “genesis-json”: “genesis.json”});fibos.load(“chain_api”);fibos.start();相关 p2p 节点地址信息可以去 http://p2pcheck.fibospubg.top… 获取。生成快照启动节点后,通过调用接口:/v1/producer/create_snapshot 生成快照,命令如下:curl http://127.0.0.1:8870/v1/producer/create_snapshot节点生成完快照后,返回结果如下:{“head_block_id”:“00003070049e51276829f6d1020fa638e5428fc9f8b0532fc60f680d72359dbe”,“snapshot_name”:”./blockData/data/snapshots/snapshot-00003070049e51276829f6d1020fa638e5428fc9f8b0532fc60f680d72359dbe.bin”}通过快照启动配置快照文件路径fibos.load(“chain”, {“snapshot”: “./blockData/data/snapshots/snapshot-00003070049e51276829f6d1020fa638e5428fc9f8b0532fc60f680d72359dbe.bin”});启动服务fibos.start();启动 EOS 节点注意: nodeos 版本: v1.4.0+通过快照启动下载快照文件:最新的快照文件地址:https://eosnode.tools/snapshotswget $(wget –quiet “https://eosnode.tools/api/snapshots?limit=1" -O- | jq -r ‘.data[0].s3’) -O snapshot.tar.gz解压快照文件tar -xvzf snapshot.tar.gz目录结构:├── node-data│ ├── snapshots└── config.ini注意:使用快照备份的方式启动时,需要保证 node-data 文件夹下无日志和状态数据文件。配置文件:vim config.iniagent-name = EOSNODEOSchain-state-db-size-mb = 10240reversible-blocks-db-size-mb = 1024http-server-address = 0.0.0.0:8870http-validate-host = falseverbose-http-errors = trueabi-serializer-max-time-ms = 2000access-control-allow-origin = *allowed-connection = anymax-clients = 2sync-fetch-span = 3000connection-cleanup-period = 30enable-stale-production = falseplugin = eosio::chain_api_pluginplugin = eosio::chain_pluginp2p-peer-address = ip:prot相关 p2p 节点地址信息可以去 https://github.com/CryptoLion… 获取快照方式启动脚本:nodeos –config-dir ./ –data-dir ./node-data –snapshot ./node-data/snapshots/snapshot-023e5e8813f687c6c5ffcf6eae853eb24f78d90b475dac4fb94face8c8308e4f.bin节点启动后目录结构:├── node-data│ ├── snapshots│ ├── blocks│ ├── state└── config.ini验证:curl http://127.0.0.1:8870/v1/chain/get_block -X POST -d ‘{“block_num_or_id”:38006282}‘返回结果为高度38006282的区块数据,返回的结果大致如下:{ “timestamp”: “2019-01-18T02:43:16.500”, “producer”: “atticlabeosb”, “confirmed”: 0, “previous”: “0243ee09128b14b56f90b3a0288b4b6f34526f53d71f8dc4e56bb89a42b4a93d”, “transaction_mroot”: “179c0382cf457b63356f733dc93bd3c582419f2b3a64e0d270e9d9238149bae4”, “action_mroot”: “e83174a2fae3c44777616993e7ba65393805a382bf423b744010873f76beaae8”, “schedule_version”: 667, “new_producers”: null, “header_extensions”: [ ], “producer_signature”: “SIG_K1_KhkTgB5PHXGmYtiZMGgHVcQKxKFh8uUFVA8Mwic8bpjA6bCFSYnNkbGqYZW23A5zBXWKvb3PnMJGEiS3MHwvPGpZzf95wd”, “transactions”: […..]}生成快照添加插件在 config.ini 中添加:plugin = eosio::producer_api_plugin注意: 开启该插件后,请确保你的节点放置在内网安全。设置备份目录启动时完整参数:nodeos –config-dir ./ –data-dir ./node-data –snapshots-dir ../snapshots-backups创建快照curl http://curl http://127.0.0.1:8870/v1/producer/create_snapshot按照目前 EOS 的大小,这一步大约需要耗时1015分钟。快照创建结束后,在 snapshots-backups 目录下,生成相应的快照文件。请求返回结果如下:{ “head_block_id”:“000006a4529a21b72b58c70c262fd3a754930d68b30b0b166f72fc1dbbc376e8”, “snapshot_name”:”./snapshots-backups/snapshot-000006a4529a21b72b58c70c262fd3a754930d68b30b0b166f72fc1dbbc376e8.bin"}适用场景搭建自己的 EOS、FIBOS API 节点只关心当前最新的区块数据、交易,无需溯源 ...

January 22, 2019 · 2 min · jiezi

Ethereum 君士坦丁堡安全漏洞对 FOD 的影响

FOD 与 Ethereum 的前世今生FOD 是 FIBOS 生态中的稳定币,与 USDC 1:1 锚定,其服务于需要稳定价值衡量的应用场景。FOD 通过跨链网关将 ETH 链上的 USDC 与 FIBOS 链上的 FOD 价值绑定。这相当于 1:1 锁定了流通 FOD 同等数量的 USDC,并提供稳定即时的双向兑换。Ethereum 君士坦丁堡升级对 FOD 的影响本次 Ethereum 君士坦丁堡升级是 Ethereum 由大都会转向宁静前的最后一次升级,升级采取的硬分叉模式,为了防止用户在升级时转账出现问题,我们决定暂时关闭 FOD 通道。由于在 2019 年 01 月 16 日凌晨,Ethereum 君士坦丁堡版本被曝出安全漏洞因此 FOD 通道重启只能延期,重启日期需要根据 Ethereum 基金会对这次安全漏洞对处理结果待定。Ethereum 君士坦丁堡安全漏洞智能合约中 address.transfer(…) 和 address.send(…) 存在重入攻击漏洞。漏洞产生的情况合约中有一个函数 A,A 中在改变状态后调用了 transfer/send 函数。这种情况有的时候不是很明显,比如二次 transfer 或者内部调用另一个智能合约必须存在一个攻击者可访问的函数 B,其中(a)改变状态,(b)状态改变与函数 A 的状态改变冲突。函数 B 执行消耗需要小于 1600 gas (2300 gas 限制 - 700 gas(为 call 提供的))为什么此次升级会产生安全漏洞在 Ethereum 拜占庭版本每个存储操作需要消耗至少 5000 gas,而 transfer/send 操作 gas 消耗要求小于 2300,在执行上述操作的时候会因为 gas 限制而无法执行。在 Ethereum 君士坦丁堡版本中,改良了 EVM 机制,从而减少了 gas 的消耗,因此出现了重入攻击的安全漏洞。Parity 客户端升级方法在这次安全漏洞之前的 Parity 客户端包含了 Ethereum 君士坦丁堡版本的升级并会在区块高度达到 7080000 时激活。针对这次的安全漏洞,Parity 官方紧急发布了新的 Parity 版本。Parity 升级方法升级指令:bash <(curl https://get.parity.io -L) -r stable验证是否更新成功parity -v得到的结果查看版本是否是 Parity-Ethereum/v2.2.7-stableParity Ethereum version Parity-Ethereum/v2.2.7-stable-b00a21f39-20190115/x86_64-macos/rustc1.31.1Copyright 2015-2018 Parity Technologies (UK) Ltd. ...

January 16, 2019 · 1 min · jiezi

FIBOS 与 Ethereum 技术对比

共识机制Ethereum 使用的是 PoW 共识机制,未来几年里将会换成 PoS 共识机制。Ethereum 区块是由矿工计算哈希产生,在 PoW 共识机制中区块需要得到全网络超过51%的节点确认才能够正式被区块链认可。在 Ethereum 网路中,任何人都可以成为矿工。FIBOS 使用的是 DPoS 共识机制。FIBOS 区块的产生是由21个 BP 轮流出块,产生的区块需要2/3以上的 BP 确认才能够被区块链认可。21个 BP 是由 FO 通证持有者投票选举出。账户/地址Ethereum 的用户使用的是地址,一个长达40位的的16进制数。FIBOS 使用的是账户管理,账户名采用12位数字与字母组合,可自定义,方便用户记忆。权限Ethereum 的权限是由地址唯一对应的私钥管理,并且这个私钥是随机生成的,在需要使用的权限的时候用户只能通过私钥授权。FIBOS 账户默认有2种原生权限: owner、active,一个账户必须“关联” owner、active 权限。owner 拥有超级权限,代表着账户的归属者,因为拥有此权限者可以用于操作其他权限配置,该权限常用事务中(转账、合约 action 等)一般不会使用。active 常用业务的权限,比如:转账、投票等。另外还可以根据自己需求自定义权限。手续费/资源Ethereum gas在 Ethereum 中使用区块链上的资源需要消耗 gas,消耗的 gas 作为区块打包的费用支付给矿工。FIBOS 资源FIBOS的资源分为两种类型:抵押型资源,包括 CPU 和 NET;消耗性资源,叫做 RAM,也称存储。开发者发布一个合约必须拥有足够的资源,包括 RAM、CPU 和 NET。智能合约编程语言的区别Ethereum 上开发智能合约使用的语言为 Solidity,这是一门专为 EVM 而开发的语言,对于一般没有接触过 Ethereum 或智能合约的开发者来说,该语言的研发门槛很高。Ethereum 合约示例:pragma solidity ^0.4.0;contract hello { function hello(uint i){ }}FIBOS 使用 JavaScript 编写智能合约,开发成本极低。这让开发智能合约的门槛降低了许多。FIBOS 合约示例:exports.hi = user => console.error(‘in contract:’, user);合约的发布和更新Ethereum 合约发布成功后会得到一个合约地址。合约地址格式长并且没有规律记忆起来十分困难。Ethereum 合约发布后无法更改。在 Ethereum 中如果合约发布后发现问题,现有两种解决方案:一个是在合约中预先设置销毁函数,并设置权限只有合约发布者可以调用,在需要的时候调用销毁函数销毁合约。另一个方法是在合约中预先设置 delegatecall,由于 delegatecall 保留了函数调用的状态,因此可以更新目标合约的逻辑,并且状态将保留在代理合约中以供更新后的目标合约的逻辑使用。这两种方法都需要预先的设置,以及发布合约的账号丢失后,也将失去对合约的控制权。FIBOS 合约账户名就是发布账户的账户名。发布合约时需要发布账号的资源,包括足够的 RAM、CPU 和 NET。在 FIBOS 中开发者可以使用发布账户随时更新合约代码。相较于以太坊的合约,FIBOS 的合约后期的维护和更新在技术上容易很多,在成本上低了很多。生态支持Ethereum:开发框架: Truffle 具有以下功能:内置的智能合约编译,链接,部署和二进制文件的管理。快速开发下的自动合约测试。脚本化的,可扩展的部署与发布框架。部署到公网或私网的网络环境管理功能使用 EthPM&NPM 提供的包管理,使用 ERC190 标准。与合约直接通信的直接交互控制台(写完合约就可以命令行里验证了)。可配的构建流程,支持紧密集成。在 Truffle 环境里支持执行外部的脚本。在 Truffle 框架中,可以根据需要编译、部署合约,Truffle 也提供一键启动测试链的工具。托管节点: InfuraEthereum 的合约可以通过使用 Infura 提供的节点发布合约。FIBOS:fibos.js 是 FIBOS 区块链的通用库,具有以下功能:使用 NPM 提供的包管理。快速开发下的自动合约测试。提供合约与客户端交互接口。提供合约内部所需的 API 接口。节点: FIBOS 提供一键脚本发布十分简单易用。FIBOS-tracker 是一个 FIBOS 区块链数据 API 服务框架,基于 fib-app 框架实现。提供对 FIBOS 区块数据的 emitter 监听事件。提供 http 服务,支持 GraphQL 调用。支持使用 ORM 定制自己的数据模型 model,自定义数据表以及自定义 hook 监听数据。 ...

January 16, 2019 · 1 min · jiezi

FIBOS DAPP 应用场景详解

在去年的 10 月, FIBOS 举办的第一季「一念巨浪」DAPP 大赛圆满结束。大赛共收到 80 多个项目咨询,其中 62 个项目报名成功,最终 29 个项目入围进行最后的路演对决!为了激励更多有梦想、有创意的开发者和项目方,第二季「一念巨浪」DAPP 征集大赛现已启动!可能有些朋友对 DAPP 还不是很了解,下面就让我们走进 DAPP 的世界。什么是 DAppApp 我们都知道是客户端应用,是 application 的简称。DApp 就是 D+App,D 是英文单词 decentralization 的首字母,单词翻译中文是去中心化,即 DApp 为去中心化应用。这是从字面上去理解这个概念,要在脑中形成清晰、准确、必要的概念,还需要深度去理解 DApp。DApp 的发展一个新技术的发展,一般会经历触发期、期望膨胀期、幻想破灭期、复苏期、价值期。 同样地,DApp 也在不断进化演变,广义地说,从最初的比特币到现在因 ICO 盛行一时的以太坊,再是各路公链崛起强大,然后是公链、联盟链、私有链齐头并进发展,最后是链上的各种应用应运而生蓬勃发展,现在我们经常说的 DApp 更多的是这样一种定义:客户端 + 智能合约 + token(通证经济)FIBOS 提供了 Javascript 语言为基础的智能合约引擎,同时提供了以 Bancor 经济模型为基础的 IBO 通证经济。之前开发一个app需要一家公司招开发人员进行开发然后推广运营,现在开发DApp可能不需要是一家公司,也可以是个人或自媒体,整个流程可以是:写白皮书明确共识机制Token激励机制智能合约开发去中心化社区自治对比APP,两者最大不同就是中心化与去中心化。App先要有钱,所以先融资;然后再有人,所以招齐人后再开发运营。而DApp则是继承传统App并结合区块链的特点所形成的产物,它更像是众筹模式、共享模式和去中心化模式,DApp先有发起人或组织,写好白皮书明确了共识机制和token分配与激励,持有token的人即为股东,直接和DApp的盈利关联(也可以说用户即是股东),持有的token像股票可以买卖,在支持的交易所交易,所以持有该DApp的token相当于拥有所有者权益。可以想象,未来各个领域都会有DApp,每个人都将因token分类、以token群分。下面让我们聊聊 DAPP 的应用场景钱包领域钱包应用每条公链上都必须有,比特币有自己的钱包,以太坊也有自己的钱包,其他公链如国内的neo、qtum都有自己的钱包。FIBOS 自主研发的 FO 钱包是一个去中心化的通用数字钱包,它可以便捷的帮助用户进行数字资产管理。FO 钱包支持 EOS 跨链转账,支持资源管理、通证兑换、多账号切换等功能,可以使用钱包发红包、转账、投票、购买资源等等。此外,钱包中还集成了多款 DAPP,涉及方方面面,有一些有趣的小游戏,还可以便捷的充话费。还有一些方便开发者使用的开发工具等等。未来 FO 钱包还会不断迭代,大家可以多多关注它的更新和动态。内容社区区块链与内容垂直领域耦合性非常好,利用区块链的特性和技术,做内容的平台越来越多,在这赛道上竞争无比激烈,据我了解的有很多,如国外的steemit,国内的币乎、币问、Primas、Pressone等。币乎侧重于内容分发,创作者发布文章和读者点赞都会有收益,通过内容平台发行的代币来打赏,建立有效的激励机制,作者、读者和平台按比例分成。作者创作优质文章,读者觉得好就点赞或转发,平台根据阅读量标记为热门文章排在前位。Primas侧重于内容确权,对创造者发布的文章会利用平台的鹰眼检测系统进行检测是否原创,若是原创就会将文章的关键字如标题、作者和发布时间等上链打包进区块;若是抄袭或有过多重复内容,则发布失败。然后Primas愿景是成为下一代价值内容生态圈,使其内容可信化、优质化。区块链防伪溯源区块链在溯源领域的应用涉及方方面面,比如说在食物供应链的溯源应用,以及在高档消费品的防伪应用。据中国防伪材料市场分析报告统计,全世界受假冒伪劣产品影响的市场金额达到了3000亿美元。18年国内消费品零售总额40万亿左右,结合各方数据推算,国内防伪溯源市场预计4000亿元左右。高档消费品的防伪溯源——源之链在防伪溯源领域,数据的安全性、真实性是痛点,区块链的去中心化、不可篡改的记账方式,改变了传统模式,让“信任”真正可信。由于区块链具有数据不可篡改的特性,数据一经上传,就无法更改,因此更容易做到来源可查、去向可追,真正实现责任可追溯。FIBOS 开发的源之链从事消费品类区块链防伪追溯业务。团队拥有洋河、双沟等多家上市公司产品追溯项目经验。技术上利用物联网、防伪码、区块链加密二维码等方案,将商品流通各环节的数据进行区块链加密处理,通过手机应用查验溯源信息。平台链通B端、C端为用户搭建了溯源产品销售、融合防伪追溯查验、扫码送积分、积分购物、积分兑换通证AF等功能。“家优鲜+区块链”模式打造信任标签随着消费升级,消费者对食品的要求越来越高。事实上,食物供应链因涉及生产、运输、仓储、销售等多个环节,在食品质量把控上极为复杂,而区块链作为一项以去中心化为核心的技术,相关数据在交易各方间公开透明,从而有效形成一条信息和价值共享的链条。 区块链在食品领域的应用还有家乐福,2018年12月6日,家乐福正式对外宣布,家乐福中国首个区块链应用落地,上链的首个“家优鲜”产品琯溪蜜柚今天正式上市。作为家乐福身体力行农产品安全高标准的项目,“家优鲜”对农产品生产进行全程追溯,不仅让处于供应链末端的消费者受惠,也向供应链上端的农业生产者提供帮助、改进种植技能、增产创收。相信区块链的使用,可有效帮助消费者重拾信心,重新建立起对食品行业的信任度。家乐福始终将食品安全与品质视为重中之重,希望借区块链推进农产品可追溯的进程,密切关注从田间到餐桌的每一个环节,为行业树立良好典范。“区块链+金融”区块链在金融领域的落地让市场变得更加方便和透明,下面来看看几个重要的应用。FINX打造去中心化银行基于 FIBOS 开发的金融类应用「FINX」在全球爆发性的无现金社会的浪潮中,对于没有银行账户的区块链银行业里,拥有先发优势,可以让更多的企业和个人用户受益。「FINX」致力于创造出一个区块链银行,可让您随时随地通过内置交易所存储,发送,接收,投资,提取,兑换和交易数码货币。DDPocket 钱包让信用创造价值再看看基于 FIBOS 开发的另一个金融类应用——「DDPocket」,「DDPocket」是实现DD货币转换成现金的平台,解除人们对于加密货币无法兑现 的疑虑。透过DD钱包,DD公司可将DD货币转卖/借贷给用户,用户也可以以现 金购入DD货币,或是将钱包里所拥有的DD货币转卖(DD公司购入),换取现金。同时,「DDPocket」还有专为大专生设计的购物平台。学生可以在DD商城内买卖物品/服务、也可在内置的交流平台寻找需要的物品/服务。DD商城内的所有交易均使用DD货币,模式可分为两项:1.消费者对消费者(C2C)学生可将自己的二手电脑、自行车、书籍、笔记等出售,亦可提供补习服务、出租房间等。2.企业对消费者(B2C)DD公司也会与各商家合作,让商家们提供各种过季优惠商品(如:手机、电脑、电单车)、学术研讨会门票、食物套餐固本、影印服务固本等。在提高商家业绩的同时,也让学生可以获得便宜的商品及服务。蚂蚁金服打造第一个区块链跨境汇款除了以上的两个应用,区块链在跨境汇款中也发挥着重要的作用。区块链跨境汇款运用了区块链技术最重要的几个能力:智能合约、共识机制、联盟记账,进而具有交易最终性、多机构联盟记账和智能合约三大能力,而这对于跨境汇款十分重要。跨境汇款中有大量的不同国家/地区、不同币种、不同金融机构、不同参与者协作,又涉及到法律监管汇率等问题,是十分复杂的金融场景,现在看来,区块链技术或许是解决这个问题的方向。在区块链领域,蚂蚁金服的普惠跨境汇款服务走在了世界的前沿。6月25日蚂蚁金服在香港发布了基于区块链技术的普惠跨境汇款服务,最先支持从香港到菲律宾的汇款:支付宝香港版即AlipayHK可向菲律宾当地电子钱包Gcash汇款,渣打银行负责日终的资金清算和货币兑换服务,基于区块链技术,跨境汇款首次进入秒级时代。区块链跨境汇款服务是全球第一个真正基于区块链的跨境汇款服务,也是蚂蚁金服第一个面向公众的基于区块链的金融服务,此前蚂蚁金服区块链技术已在公益捐款、商品正品溯源、保险追踪、租房管理上应用,这一次终于将区块链应用到蚂蚁金服最核心的金融服务最核心的汇款转账场景上。“区块链+游戏”目前区块链游戏大多是博彩性质的,前段时间许多博彩游戏被黑客攻击,导致玩家损失惨重。我们希望能出现一些把游戏和区块链生态结合在一起的优质游戏。众所周知, DAPP 一直与游戏结合紧密,区块链生态系统下的游戏将打破盈利壁垒,让每一位玩家及推荐者与贡献者都能获得收益,让每一个为生态扩张做贡献的节点,他们的付出都有回报。我们把大部分的盈利都返还给有贡献的节点。通过激励与奖励,让所有人自发参与传播和维护实现快速增长。下面就来看看基于 FIBOS 开发的游戏类应用——加密星球吧。加密星球利用生态激励激活每一个生态节点,让所有参与者与贡献者有奖励,让他们创造的价值被保护。让每个传播者,都应该获得理所应当的收入;用户真实拥有游戏内资产,并可借助智能合约去信任流通;区块链的跨应用账本特性,使同款IP资产可以被复用,大大增加游戏间的交互性及玩法。重塑游戏内经济体系。玩家的投资,每天都应该按贡献分红。“区块链+旅行”旅行中大家会遇到很多订票问题,不胜烦扰,区块链落地于旅游行业可以让你的出行更加快捷。区块链旅行项目通过区块链技术的去中心化旅行服务体系,链接全球旅行服务提供者与消费者,构建透明、可信、高性价比的未来旅行生态链,打造一个“省钱又省心的旅游神器”。“旅游+区块链”打造复合型旅游区块链生态圈2018年7月26日,区块链旅行平台星牛旅行日前对外推出APP端产品,将于8月27日正式上线。星牛旅行是基于区块链技术的去中介化旅行服务体系,通过链接全球旅行服务提供者(企业或个人)与消费者,构建透明、可信、廉价、去中介化的未来旅行生态链。星牛旅行前端应用同时由一系列智能合约完成内部的信息交互和指令执行,在后端,将结合底层服务公有、私有链自身属性和旅游生态行业的特点,涵盖不同的消费、金融、内容、社交等场景,对应不同的技术架构,从而达成复合型旅游区块链生态圈。区块链让旅行更加快捷之前,旅游市场几乎全部的交易都被OTA垄断,第三方在提供了信息聚合、细分品类、预定保障等服务的同时,也收取了一定比例的佣金,这些成本都转变为用户高昂的出行费用。区块链旅行通过区块链网络去中心化智能合约体系,将能提供比友商平台更低15%~20%的价格,其可追溯、不可篡改性也对买卖双方的权益与隐私进行保护。物联网+人工智能DApp 被大多数人看好的方向在于和物联网、共享经济的结合,比如无人驾驶汽车应用。传统上,一辆无人驾驶汽车得到路况信息需要先传输到中心化服务器,然后服务器再传输给另一辆无人驾驶汽车,若出现服务器故障或者传输网络延迟等情况,汽车之间没有及时通信,路况又是随时变化的,所以就很容易出现事故。如果汽车与汽车能直接通信,一辆无人驾驶汽车实时将路况信息写入区块链,其他无人驾驶汽车则可及时获取路况信息并及时调整,这样要好于中心化管理。除了上面利用区块链技术做到汽车与汽车之间的信息通信,人工智能也可以充分利用区块链技术加智能合约,做到机器与机器之间的通信交流。借用《浪潮之巅》作者吴军老师的说法:人工智能 + 区块链 + 智能合约=超级智能欢迎大家报名第二届【一念巨浪】 DAPP 大赛以上介绍的 DAPP 应用,希望能够对大家开发 DAPP 有所帮助。同时请对 DAPP 有兴趣的开发者参加 FIBOS 举办的第二届【一念巨浪】 DAPP 大赛,本次大赛已获得 20 多家机构、社区、媒体的大力支持,其中包括创世资本、节点资本、BKFUND、拜占庭资本等知名投资机构;HelloEOS、EOSAsia、IMEOS、BCCN 等强影响力社区;慢雾科技、比特派、BeeDApp、ENU 等多个生态合作伙伴;巴比特、币快报等深度合作媒体。同时获得东南大学区块链实验室等高校学术机构的指导。 ...

January 14, 2019 · 1 min · jiezi

【跟着源码学】EOS智能合约之eosio.system - part1

本系列还是着眼于了解EOS的设计理念,力求在繁杂的版本变更,以及各种区块链技术文章当中,根据源码整理出一个清晰简明的eos实现,而暂时不着眼研究C++工程开发的奇淫巧技,主要是因为还需要时(目)间(前)继(领)续(悟)修(不)炼(到)。正文代码链接这个multi_index是什么呢?在eoslib目录下有multi_index.hpp,自然而然的来看看这里面有什么线索。在这里,找到了如下解释:EOSIO Multi-Index API provides a C++ interface to the EOSIO database. It is patterned after Boost Multi Index Container.EOSIO Multi-Index table requires exactly a uint64_t primary key. For the table to be able to retrieve the primary key,the object stored inside the table is required to have a const member function called primary_key() that returns uint64_t.EOSIO Multi-Index table also supports up to 16 secondary indices. The type of the secondary indices could be any of:uint64_tuint128_tuint256_tdoublelong double原来multi_index是跟EOSIO数据库相关的API。相对应的,官方开发者文档有DB API的描述,简要解释一下使用场景:比如开发一个游戏DApp,用户有自己的Action(很难翻译,可以理解为执行一个函数,比如randint(6),模拟了一次掷骰子,返回结果从1至6)操作, 该游戏智能合约要记录每位用户游戏Actions,本次合约执行完毕后数据不能丢失,就需要将数据存储到 EOS 数据库中。Action在被称为Action执行上下文的环境中运作。如下图所示,Action上下文提供执行Action所需的几件事情。其中一件事是Action的工作内存。这是Action执行的地方。在处理一个Action之前,EOSIO为该Action进行一次内存清理工作。在新Action的上下文中当另一个Action执行时可能已经被设置的变量不可用。在Action中传递状态的唯一方法是将其持久存储并从EOSIO数据库中检索。声明看到这里,感觉引入概念越来越多,暂时先搬运了一些现成资料(见参考),再后续学习中慢慢消化。这里提到了eosio::multi_index table借鉴了Boost库中的multi_index容器(Boost库中的mult_index)。可以在概念上看作传统数据库中的表格,其中行是容器中的单个对象,列是容器中对象的成员属性,并且索引通过与一个键兼容的键提供对对象的快速查找 对象成员属性。传统的数据库表允许索引成为表中某些列数的用户定义函数。eosio::multi_index同样允许索引是任何用户定义的函数。但其返回值仅限于受支持的一组受限密钥类型之一。传统数据库表通常有一个唯一的主键,它允许明确标识表中的特定行,并为表中的行提供标准排序顺序。eosio::multi_index支持类似的语义,但是该对象的主键在eosio::multi_index容器必须是唯一的无符号64位整数。eosio::multi_index中的对象容器按主键索引按无符号64位整数主键的升序排序。智能合约无法直接操作存储在硬盘中的数据表,而是需要使用multi_index作为中间工具(或者叫容器),每个multi_index实例都与一个特定账户的特定数据表进行交互(取决于实例化时的参数)。EOS智能合约与EOS数据库的数据交互如下图所示。每一个multi_index都相当于传统数据库的一个数据表(table),但将传统数据库的行与列的形式改为了单纯的列。也就是说multi_index是一个线性排列的表,只有一列,每一行都只存储一个对象。但是一般来说multi_index存储的对象都是结构体或者类,里面含有多个成员变量,所以multi_index存储数据的灵活性也是不亚于传统数据库的。我们使用官方的“汽车维修店”示例,我们建立一个数据表,储存每个汽车维修店客户的账户名、保养时间、车辆里程。那么multi_index数据表储存的项目中,每个都是如下的结构体:struct service_rec { uint64_t pkey; // 主键 account_name customer; // 车主用户名 uint32_t service_date; // 维修保养时间 uint32_t odometer; // 车辆里程}在传统数据库中,需要建立一个 4 列的数据表,用来储存每个用户的这个 4 个数据,而multi_index的每个数据表只有一列,只存储每个用户的 service_rec 整个结构体即可。下图为multi_index数据结构。多索引迭代器(multi_index iterator),与仅提供键值(key-value)存储的其他区块链不同,EOSIO Multi-Index表允许合约开发人员保存按照各种不同键类型排序的对象集合,这些键类型可以从对象内的数据派生。这使得丰富的检索功能。最多可以定义16个二级索引,每个索引都有自己的排序和检索表格内容的方式。EOSIO多索引迭代器遵循C++迭代器通用的模式。所有迭代器都是双向常量,可以是const_iterator或const_reverse_iterator。迭代器可以取消引用以提供对多索引表中的对象的访问。在 EOS 数据库中,可以将迭代器比喻为一个“电梯”,在整个数据表中上下穿梭。所有对数据的操作必须通过迭代器完成。典型的数据修改过程是这样的:首先使用迭代器的find()方法,在特定的索引中寻找需要的数据,比如在车主用户名索引中寻找某个用户。迭代器会移动到需要的数据对象上。然后就可以使用迭代器的modify()方法修改当前迭代器对应的数据。下图为迭代器指向用户 Sue 的情况。参考EOS多索引表EOS 数据库与持久化 API —— 架构 ...

January 11, 2019 · 1 min · jiezi

如何在 fibos 上创建快照和使用快照启动节点

本文介绍下如何通过快照启动 FIBOS 节点。快照创建无需停止节点打包数据比备份数据更方便快捷。如果还不清楚如何启动一个 fibos 节点请参考 启动 fibo节点fibos 版本 v1.4.1+如何创建快照1.配置快照目录快照生成位置 config.data_dir 为根目录,可以配置例1config.data_dir = “./blockData/data”;fibos.load(“producer”, { “snapshots-dir”: “snapshots”});那么快照生成位置为 ./blockData/data/snapshots例2config.data_dir = “./blockData/data”;fibos.load(“producer”, { “snapshots-dir”: “../snapshots”});那么快照生成位置为 ./blockData/snapshots2. 载入producer_apifibos.load(“producer_api”);3.生成快照curl http://127.0.0.1:8870/v1/producer/create_snapshot例1 调用结果{ “head_block_id”:“00003070049e51276829f6d1020fa638e5428fc9f8b0532fc60f680d72359dbe”, “snapshot_name”:"./blockData/data/snapshots/snapshot- 00003070049e51276829f6d1020fa638e5428fc9f8b0532fc60f680d72359dbe.bin"}例2 调用结果{ “head_block_id”:“000006a4529a21b72b58c70c262fd3a754930d68b30b0b166f72fc1dbbc376e8” “snapshot_name”:"./blockData/data/./snapshots/snapshot-000006a4529a21b72b58c70c262fd3a754930d68b30b0b166f72fc1dbbc376e8.bin"}如何通过快照启动1.配置快照文件路径例1fibos.load(“chain”, { “snapshot”: “./blockData/data/snapshots/snapshot-00003070049e51276829f6d1020fa638e5428fc9f8b0532fc60f680d72359dbe.bin”});例2fibos.load(“chain”, { “snapshot”: “./blockData/snapshots/snapshot-00003070049e51276829f6d1020fa638e5428fc9f8b0532fc60f680d72359dbe.bin”});2.启动服务fibos.start();

January 10, 2019 · 1 min · jiezi

原创| DPOS 3.0 + BFT 为什么需要 2 次 2/3 共识

很多读者都很关心 BM 和 V神 在 EOS issue 上对于 DPOS 的机制的讨论,接下来我们具体讨论下他们的讨论内容。我们先来讲述一下最初 EOS 的 DPOS + BFT 的共识机制:当一个特定的区块被 ( 2/3 + 1 ) 生产者确认的时候,该块成为不可逆块。假设现在有 A, B 和 C 三个 BP。情况 a: A 生产了一个区块 N, B 生产区块 N + 1 并且确认了区块 N, C 生产区块 N + 2 并且确认了区块 N, N +1 , 此时 N 已经有 3 个确认,达到了 2/3 + 1 个确认,则区块 N 成为不可逆。情况 b: A 生产一个区块 Na, B 生产一个区块 Nb, C 在 Nb 的基础上生产一个区块 N + 1, 此时发现 两个区块 N( Na 和 Nb ) 都不能达到 2/3 + 1 的确认数了,那岂不是永远不会不可逆了?假如此时 A 在 N + 1 的基础上生产区块 N + 2, B 生产区块 N + 3, 此时区块 N + 1 达到了不可逆的,那么 N + 1 所在的该分叉上小于等于 N + 1 的都会变成不可逆, 也就是 Nb 也变成不可逆。提出问题上面所述的只经过了一次共识,那么会出现什么问题呢。V 神就在 issue 上提出一个例子。可以看出第一条链 A 生产的 101 经过 B、C 已经达到了 3 个确认数已经成为不可逆了, 但此时 D 因网络不好, 没接收到这些块, 从而产生分叉开始生产区块 101 , 之后 A 生产区块 102 , 因为块高度大于之前的 101 所以是可生产的,B同理, 经过 A B 之后 D 生产的 101 同样达到了 三个确认数, 这样就会有 2 个块高度为 101 的区块成为了不可逆,造成 conflict。为什么会造成这个原因呢?因为区块 101 没有经过所有节点就成为不可逆了, 导致后面的产生的区块 101 可在下一轮被确认成为不可逆块。如果说 A ,B ,C ,D 都确认了区块 101, 那么下一轮谁都没可能生产块高度为 101 的区块。也就不会同时出现 2 个不可逆块了。 但全部节点确认才成为不可逆这就破坏了引入 BFT 的想法, 而且你没办法保证所有节点都会对他进行确认,毕竟网络波动的原因会一直存在。那怎么解决不可逆块冲突, 但是又不会破坏 BFT 的想法呢。那我们可以继续使用 BFT 的思想, 也就是破坏掉第二个区块 101成为 lib 的条件。PLIB这里引进 proposed lib的概念, 即资格成为 lib 的区块,简称 plib。一个区块经过 2/3 + 1共识后,他不会立马成为 lib, 会先成为 plib, 然后再 plib 经过 2/3 共识后才会成为lib。解决问题由上图,区块101 成为了 lib, 那么代表 plib 高度至少是 105 了,也就是 7 个节点中至少有五个生产的区块高度达到了 110, 这时候,假如一个 E 生产出区块 101, 那么至少需要 2/3 的节点帮他确认成为 plib,也就是有节点能生成 102 - 105,需要 4 个节点,但是 7 个 BP 已经有 5 个的块高度达到了 110,根本就不够节点能让 区块 101 成为不可逆, 那么就不会有 2 个 相同 block_num 的 lib 存在了。也就是当 N 能成为 lib 的时候,根本没有任何情况能让 2 个 N 同时成为 plib ( 当这里的 N 成为 lib 是排除掉因为 N + m 成为 lib 才使 N 成为 lib 的情况 )。其实这种方式你可以看成几条带 plib 的分叉链, BP 节点对这些链进行 2/3 共识来选出哪条 plib 分叉链作为主链,丢弃掉其他 plib 分叉链。总结: dpos 3.0 + BFT 有最初的一次共识增加到了2次,避免掉出现 conflict lib , 但是这也让 head block num 和 lib 的高度拉到至少 2 2/3 21 * 12 = 336 个块( 这种计算方式是忽略 BP 漏块的情况 )。用时间算比较准确也就是 168 秒。 还有不要嫌字迹不清晰, 写到一半笔没墨水了,我也没办法 T T以上为个人见解,如有错误或者缺漏,还请指正哈。参考文章:https://github.com/EOSIO/eos/…https://medium.com/eosio/dpos…转载请注明来源: https://eos.live/detail/19947 ...

January 8, 2019 · 2 min · jiezi

eosjs 文档(Serialize接口)

Serialize接口Action属性account:string定义于eosjs-serialize.ts:92authorization:Authorization[]定义于eosjs-serialize.ts:94data:any定义于eosjs-serialize.ts:95name:string定义于eosjs-serialize.ts:93Authorization属性actor:string定义于eosjs-serialize.ts:86permission:string定义于eosjs-serialize.ts:87Contract属性actions:Map<string, Type>定义于eosjs-serialize.ts:81types:Map<string, Type>定义于eosjs-serialize.ts:82CreateTypeArgs属性<Optional> aliasOfName:string定义于eosjs-serialize.ts:738<Optional> arrayOf:Type定义于eosjs-serialize.ts:739<Optional> base:Type定义于eosjs-serialize.ts:743<Optional> baseName:string定义于eosjs-serialize.ts:742<Optional> deserialize:function定义于eosjs-serialize.ts:746类型声明(buffer: SerialBuffer, state?: SerializerState, allowExtensions?: boolean): any参数:名称类型bufferSerialBufferOptional stateSerializerStateOptional allowExtensionsboolean返回:any<Optional> extensionOf:Type定义于eosjs-serialize.ts:741<Optional> fields:Field[]定义于eosjs-serialize.ts:744<Optional> name:string定义于eosjs-serialize.ts:737<Optional> optionalOf:Type定义于eosjs-serialize.ts:740<Optional> serialize:function定义于eosjs-serialize.ts:745类型声明(buffer: SerialBuffer, data: any, state?: SerializerState, allowExtensions?: boolean): void参数:名称类型bufferSerialBufferdataanyOptional stateSerializerStateOptional allowExtensionsboolean返回:voidField属性name:string定义于eosjs-serialize.ts:12字段名称。type:Type定义于eosjs-serialize.ts:18字段的类型。typeName:string定义于eosjs-serialize.ts:15字符串形式的类型名称。SerializedAction属性account:string定义于eosjs-serialize.ts:100authorization:Authorization[]定义于eosjs-serialize.ts:102data:string定义于eosjs-serialize.ts:103name:string定义于eosjs-serialize.ts:101SerializerOptions属性<Optional> bytesAsUint8Array:boolean定义于eosjs-serialize.ts:23Symbol属性name:string定义于eosjs-serialize.ts:74符号的名称,不包括精度。precision:boolean定义于eosjs-serialize.ts:77小数点后的位数。Type属性aliasOfName:string定义于eosjs-serialize.ts:44类型名称的别名,如果有。arrayOf:Type定义于eosjs-serialize.ts:47类型这是一个数组,如果有。base:Type定义于eosjs-serialize.ts:59这种类型的基础,如果这是一个结构。baseName:string定义于eosjs-serialize.ts:56此类型的基本名称(如果这是结构)。deserialize:function定义于eosjs-serialize.ts:68从二进制形式转换到buffer中的数据。类型声明(buffer: SerialBuffer, state?: SerializerState, allowExtensions?: boolean): any参数:名称类型bufferSerialBufferOptional stateSerializerStateOptional allowExtensionsboolean返回:any<Optional> extensionOf:Type定义于eosjs-serialize.ts:53标记二进制扩展字段。fields:Field[]定义于eosjs-serialize.ts:62包含的字段,如果这是一个结构。name:string定义于eosjs-serialize.ts:41类型名称。optionalOf:Type定义于eosjs-serialize.ts:50类型这是可选的,如果有。serialize:function定义于eosjs-serialize.ts:65将data转换为二进制形式并存储在buffer中。类型声明(buffer: SerialBuffer, data: any, state?: SerializerState, allowExtensions?: boolean): void参数:名称类型bufferSerialBufferdataanyOptional stateSerializerStateOptional allowExtensionsboolean返回:void上一篇:Serialize类

January 7, 2019 · 1 min · jiezi

eosjs 文档(Serialize类)

Serialize类SerialBuffer构造函数new SerialBuffer(__namedParameters?: object): SerialBuffer定义于eosjs-serialize.ts:118参数:Default value __namedParameters:objectarray:如果序列化或要反序列化的二进制数据,则为null。textEncoder:要使用的TextEncoder实例,如果在浏览器中运行,则传入null。textDecoder:要使用的TextDecider实例,如果在浏览器中运行,则传入null。名称类型arrayUint8ArraytextDecoderTextDecodertextEncoderTextEncoder返回:SerialBuffer属性arrayarray:Uint8Array定义于eosjs-serialize.ts:112序列化(二进制)形式的数据。lengthlength:number定义于eosjs-serialize.ts:109array中的有效数据量。readPosreadPos:number = 0定义于eosjs-serialize.ts:115读取时的当前位置(反序列化)。textDecodertextDecoder:TextDecoder定义于eosjs-serialize.ts:118textEncodertextEncoder:TextEncoder定义于eosjs-serialize.ts:117方法asUint8ArrayasUint8Array(): Uint8Array定义于eosjs-serialize.ts:159删除多余存储后返回数据。返回:Uint8Arraygetget(): number定义于eosjs-serialize.ts:176获取单个字节。返回:numbergetAssetgetAsset(): string定义于eosjs-serialize.ts:475获取asset。返回:stringgetBytesgetBytes(): Uint8Array定义于eosjs-serialize.ts:375获取带长度前缀的二进制数据。返回:Uint8ArraygetFloat32getFloat32(): number定义于eosjs-serialize.ts:294获取float32。返回:numbergetFloat64getFloat64(): number定义于eosjs-serialize.ts:304获取float64。返回:numbergetNamegetName(): string定义于eosjs-serialize.ts:340获取name。返回:stringgetPrivateKeygetPrivateKey(): string定义于eosjs-serialize.ts:507获取私钥。返回:stringgetPublicKeygetPublicKey(): string定义于eosjs-serialize.ts:493获取公钥。返回:stringgetSignaturegetSignature(): string定义于eosjs-serialize.ts:521获得签名。返回:stringgetStringgetString(): string定义于eosjs-serialize.ts:385获取字符串。返回:stringgetSymbolgetSymbol(): object定义于eosjs-serialize.ts:426获取symbol。返回:objectgetSymbolCodegetSymbolCode(): string定义于eosjs-serialize.ts:403获取symbol_code,与symbol不同,symbol_code不包含精度。返回:stringgetUint16getUint16(): number定义于eosjs-serialize.ts:207获取uint16。返回:numbergetUint32getUint32(): number定义于eosjs-serialize.ts:220获取uint32。返回:numbergetUint64AsNumbergetUint64AsNumber(): number定义于eosjs-serialize.ts:239获取uint64作为number,注意:number只有53位精度,有些值会改变,建议使用numeric.binaryToDecimal(serialBuffer.getUint8Array(8))。返回:numbergetUint8ArraygetUint8Array(len: number): Uint8Array定义于eosjs-serialize.ts:192获取len个字节。参数:名称类型lennumber返回:Uint8ArraygetVarint32getVarint32(): number定义于eosjs-serialize.ts:279获取varint32。返回:numbergetVaruint32getVaruint32(): number定义于eosjs-serialize.ts:259获取varuint32。返回:numberhaveReadDatahaveReadData(): boolean定义于eosjs-serialize.ts:149有数据可供读取吗?返回:booleanpushpush(…v: number[]): void定义于eosjs-serialize.ts:171附加字节。参数:名称类型Rest vnumber[]返回:voidpushArraypushArray(v: number[] | Uint8Array): void定义于eosjs-serialize.ts:164附加字节。参数:名称类型vnumber[] | Uint8Array返回:voidpushAssetpushAsset(s: string): void定义于eosjs-serialize.ts:440附加asset。参数:名称类型sstring返回:voidpushBytespushBytes(v: number[] | Uint8Array): void定义于eosjs-serialize.ts:369附加长度前缀的二进制数据。参数:名称类型vnumber[] | Uint8Array返回:voidpushFloat32pushFloat32(v: number): void定义于eosjs-serialize.ts:289附加float32。参数:名称类型vnumber返回:voidpushFloat64pushFloat64(v: number): void定义于eosjs-serialize.ts:299附加float64。参数:名称类型vnumber返回:voidpushNamepushName(s: string): void定义于eosjs-serialize.ts:309附加name。参数:名称类型sstring返回:voidpushNumberAsUint64pushNumberAsUint64(v: number): void定义于eosjs-serialize.ts:230附加一个uint64,注意:number只有53位精度。参数:名称类型vnumber返回:voidpushPrivateKeypushPrivateKey(s: string): void定义于eosjs-serialize.ts:500附加私钥。参数:名称类型sstring返回:voidpushPublicKeypushPublicKey(s: string): void定义于eosjs-serialize.ts:486附加公钥。参数:名称类型sstring返回:voidpushSignaturepushSignature(s: string): void定义于eosjs-serialize.ts:514附加签名。参数:名称类型sstring返回:voidpushStringpushString(v: string): void定义于eosjs-serialize.ts:380附加一个字符串。参数:名称类型vstring返回:voidpushSymbolpushSymbol(__namedParameters: object): void定义于eosjs-serialize.ts:416附加symbol。参数:__namedParameters:object名称类型namestringprecisionnumber返回:voidpushSymbolCodepushSymbolCode(name: string): void定义于eosjs-serialize.ts:390附加symbol_code,与symbol不同,symbol_code不包含精度。参数:名称类型namestring返回:voidpushUint16pushUint16(v: number): void定义于eosjs-serialize.ts:202附加一个uint16。参数:名称类型vnumber返回:voidpushUint32pushUint32(v: number): void定义于eosjs-serialize.ts:215附加一个uint32。参数:名称类型vnumber返回:voidpushUint8ArrayCheckedpushUint8ArrayChecked(v: Uint8Array, len: number): void定义于eosjs-serialize.ts:184在v中附加字节,如果len与v.length不匹配则抛出。参数:名称类型vUint8Arraylennumber返回:voidpushVarint32pushVarint32(v: number): void定义于eosjs-serialize.ts:274附加varint32。参数:名称类型vnumber返回:voidpushVaruint32pushVaruint32(v: number): void定义于eosjs-serialize.ts:246附加varuint32。参数:名称类型vnumber返回:voidreservereserve(size: number): void定义于eosjs-serialize.ts:135如果需要至少有size字节空闲,请调整array的大小。参数:名称类型sizenumber返回:voidrestartReadrestartRead(): void定义于eosjs-serialize.ts:154从头开始重新开始读取。返回:voidSerializerState构造函数new SerializerState(options?: SerializerOptions): SerializerState定义于eosjs-serialize.ts:31参数:名称类型默认值Default value optionsSerializerOptions{}返回:SerializerState属性optionsoptions:SerializerOptions定义于eosjs-serialize.ts:28skippedBinaryExtensionskippedBinaryExtension:boolean = false定义于eosjs-serialize.ts:31是否已跳过任何二进制扩展名?上一篇:Serialize ...

January 7, 2019 · 1 min · jiezi

FIBOS 周报

FIBOS 稳定币的上线2018年12月21日,FIBOS 发布了稳定币—— FOD,并且成功通过了社区多签。2018年12月28日, FIBOS 的稳定币 FOD 正式上线。早在2018年9月,全球市场在一个月时间内爆发出现了十多种稳定币,市场规模达到了30亿美元。FIBOS 生态中有不少项目在实体经济落地时需要保障项目价值的稳健发展,需要以稳定币作为通证准备金,为满足生态的发展需求,服务于区块链项目落地的稳定币—— FOD 应运而生。FOD 在 FIBOS 生态中的价值体现FIBOS 默认提供了以 IBO 为基础经济模型的发币方式。然而,作为 Bancor 准备金的区块链资产价格受市场影响波动大,又不利于实体项目的落地和发展。因此,需要一种价值相对稳定,价格变化幅度小的的区块链资产作为准备金,这也就是常说的“稳定币”。FOD 在 FIBOS 生态中如何使用目前市场上有十多种稳定币项目,全球最大也是最早的稳定币 USDT 财务监管不透明,好几次都出现了「脱锚」的现象,所以我们没有选择 USDT 作为我们锚定的稳定币。经过 FIBOS 研发团队研究,最终 FIBOS 选择监管更严、财务更透明的 USDC 作为稳定币来源。通过去中心化的跨链技术生成稳定币 FOD,USDC 与 FOD 是1:1锚定。具体而言,FOD 主要用途如下:1.以 FOD 作为项目准备金,发行项目的智能通证。2.基于 Bancor 模型发行的项目稳定币,与 FOD 是1:1锚定。对于项目方来说,可以选择以 FOD 做准备金,发行项目的智能通证,当 cw=100%时,发行的智能通证就是项目自己的“稳定币”。3.以项目稳定币为准备金,发行项目的智能通证。目前,基于 FIBOS 平台有多个项目正在规划基于稳定币发行项目通证。比如,全球最大的游戏虚拟资产交易平台,比价器项目;进口美国高端 Jeep 整车改装项目;拥有一万多会员的酒吧众筹项目等等。相信 FDO 的出现会让更多的项目成功落地到实体经济,促进整个生态系统的良性发展!深圳率先试点区块链电子发票微信上线开票功能,深圳开出全国第一张区块链发票2018年7月2日,国家税务总局批复授权深圳成为全国首个试点区块链电子发票的城市。12月11日,许多深圳市民发现,微信支付的菜单中,多了一个“开发票”的选项。只需按动屏幕,短短1分钟,便可完成从付款到完成开票的全过程。深圳市税务局局长张国钧介绍“这是我们与腾讯公司合作开发的微信支付开具区块链电子发票功能。”,今年下半年,深圳开出了全国第一张区块链发票。此次微信开票功能的上线,意味着区块链电子发票,正式走入了深圳市民的日常生活。交易数据即发票信息,区块链电子发票方便市民“交易即开票”是区块链电子发票最大的特点。区块链电子发票是“互联网+税务”的深度融合产物,是完全依靠算法、而非人力开具出来的消费和支付凭证。区块链电子发票区别于传统电子发票之处,在于其以区块链技术实现加密处理,具有“分布式”存储、可追溯、不可篡改的优势,通过“资金流+发票流”的合二为一,将发票开具与线上支付相结合,实现了“交易数据即发票信息”。如今,顾客通过微信付款后,“付款通知”下方比往常多了“开发票”按钮。顾客只需点击按钮,便可调取微信“我的发票抬头”功能,完成开票操作,整个过程不到1分钟。据 FIBOS 团队调研发现,腾讯内部其实有孵化一个联盟链项目 Trust SQL。目前暂未开源,其目标是结合自有的腾讯云来打造一个「区块链 BAAS」服务。跟深圳税务局合作的这个区块链电子发票服务有没有使用到这个项目,也不得而知。总体而言,对于像腾讯这样的大公司进入区块链领域,并且真正实施一些落地项目,对区块链领域是一个重大利好。区块链发票渗入209家企业,有助于税务查验深圳市税务局统计,目前全市已有7家开票服务商及1个报销平台与区块链电子发票系统实现了对接。截至2018年12月12日,已上线的32家试点企业共开具区块链电子发票17570张,现已完成注册接入企业涉及餐饮业、停车服务、零售业、互联网服务、金融业等行业共计209家企业。2019年1月1日,六大个税抵扣、社会保险费由税务部门统一征收等一批新规正式实施。今年的个税新规受到社会各界的广泛关注,大家普遍反映中产阶级得到了实惠。在未来,相信区块链落地个税查验也将会离我们越来越近,以后大家也可以通过区块链技术更加详细的了解自己的个税情况。响马畅谈区块链现状及未来公链未来的演化路径会是怎样的很多时候我们会从历史的发展来考虑未来。比如说最初的从比特币到以太坊,是去中心化不断演变的一个过程。很多人认为弱去中心化的就不是区块链的,这样先入为主的观念约束了我们对未来发展的想法和判断,以后很多的区块链可能不是公链,可能是联盟链、私有链,共同组合成类似万链的、多级分层网状结构,响马认为这是区块链的未来,公链的需求会越来越小。等再到下一个阶段呢,社会对公链的需求会再次提升。但那个时候对公链的需求和现在又完全不同。区块链和传统行业如何结合响马认为区块链的商业化和产业化会很快到来,社会化会更晚一些。商业化和产业化是需要真正在供给侧和产业相结合,创造更多的产能、提高效率,而社会化更多需要挖掘区块链 to C 的特性,如果目前不能在供给侧创造出价值的话,那么面向 C 端现在还是略微早了一些。区块链的繁荣生态是什么样子?一个好的互联网生态,一定是用户可以通过互联网享受到更多的服务,比如抖音、淘宝、微信等等;同样,一个好的区块链生态繁荣起来也需要为用户提供足够多的优质服务,至于这些服务是什么,现在还很难想象得到。这个过程是需要我们去摸索的。未来的公链更像是 to C 的产品,响马认为接下来两年里面,可能区块链对标的应该是 to B 的产品。现阶段如果直接面向大规模用户提供服务,很容易遇到很多问题,因为 to C 对用户的体验要求是很高的,to B 的产品在现阶段是有需求和用户体验忍受能力的,接下来2年,to B 能够解决多少问题,是决定区块链能不能跑出赛道的最根本的方向。区块链能改善”技术不值钱“的处境吗?响马表示区块链解决的问题并不会让技术、或者让生产力更值钱,很多人说区块链能改善生产关系。其实我更加认为,区块链能降低价值流通的成本,让价值传递更快、成本更低,将更碎片化的资产传递给对方,如果能实现,受益的不仅仅是程序员,而是整个行业。区块链安全—— EOS 遭到回滚攻击2018-12-28凌晨,攻击 BetDice、ToBet 等游戏的黑客团伙再次对 LuckyMe、GameBet 发动攻击,造成数千 EOS 的损失。此次黑客采用的手法有别于上一次的攻击。本次的攻击为针对项目方的重放攻击。受攻击游戏的列表游戏类别时间游戏名损失值竞猜类12.18晚-12.19凌晨EOSMAX55000EOS竞猜类12.18晚-12.19凌晨ToBet22000EOS竞猜类12.18晚-12.19凌晨BigGame14903.18EOS竞猜类12.18晚-12.19凌晨BetDice200000EOS竞猜类12.18晚-12.19凌晨TRUSTBET11501EOS据 PeckShield 报道,其中的竞猜类游戏 BetDice 近一周日均活跃度超 5,000 人,交易额也在 5,000 万 EOS 以上。PeckShield 创始人蒋旭宪表示,这次攻击背后是同一个团伙或个人。攻击 BetDice 的账号 hnihpyadbunv 创建了账号 eykkxszdrnnc,用来攻击 EOSMax 与 BigGame。账号 eykkxszdrnnc 又创建了子账号 kfexzmckuhat 用来攻击 ToBet。攻击成功后,再频繁创建子账户转移所得资产。回滚攻击手法分析我们知道 EOS 采用的共识算法是 DPOS 算法,采用的是 21 个超级节点轮流出块的方式。除了 21 个超级节点外的其他全节点,并没有出块的权限。起到的作用是将收到的交易广播出去,然后超级节点将其进行打包。说到这里,很容易看出,如果一笔交易是发给除了超级节点外的其他全节点,这笔交易会经历两个过程。首先,这笔交易先被全节点接收,然后交易再被节点广播出去进行打包。而一笔交易是需要超级节点中超过 2/3+1 的节点进行确认之后才是不可回滚的,也就是不可逆的。这个过程大概需要 3 分钟左右,也就是说,交易发到除了超级节点外的全节点的时候,由于全节点没有打包的权利,此时此刻交易仍然处于可逆状态这是一个核心关键点。每一个 bp(超级节点),都可以在自己的节点的 config.ini 文件内进行黑名单的配置,在黑名单中的帐号是不能进行交易的,也就是说无论怎样,黑名单的交易都会被回滚。防御建议1、针对 DApp 的防御建议(1)节点开启 read only 模式,防止节点服务器上出现未确认的块 (2)建立开奖依赖,如订单依赖,开奖的时候判断订单是否存在,就算在节点服务器上开奖成功,由于在 bp 上下注订单被回滚,所以相应的开奖记录也会被回滚。2、针对交易所和中心化钱包的防御建议建议 EOS 交易所及中心化钱包在通过 RPC 接口 get_actions 查询热钱包充值记录时,应检查充值 transaction 所在的 block_num 是否小于 last_irreversible_block(最新不可逆区块),如果 block_num 大于 last_irreversible_block 则表示该区块仍然是可逆的,存在“假充值”风险。3、项目方在玩家下注的时候校验交易中的 actor 和 from 是否是同一帐号。4、节点要实时更新黑名单。 ...

January 4, 2019 · 1 min · jiezi

eosjs 文档(Serialize)

Serialize类SerialBufferSerializerState接口ActionAuthorizationContractCreateTypeArgsFieldSerializedActionSerializerOptionsSymbolType函数arrayToHexblockTimestampToDatecheckDateParsecheckRangecreateInitialTypescreateTypedateToBlockTimestampdateToTimePointdateToTimePointSecdeserializeActiondeserializeActionDatadeserializeArraydeserializeExtensiondeserializeOptionaldeserializeStructdeserializeUnknowndeserializeVariantgetTypegetTypesFromAbihexToUint8ArrayserializeActionserializeActionDataserializeArrayserializeExtensionserializeOptionalserializeStructserializeUnknownserializeVariantstringToSymbolsupportedAbiVersionsymbolToStringtimePointSecToDatetimePointToDatetransactionHeader函数arrayToHexarrayToHex(data: Uint8Array): string定义于eosjs-serialize.ts:592将二进制数据转换为十六进制。参数:名称类型dataUint8Array返回:stringblockTimestampToDateblockTimestampToDate(slot: number): string定义于eosjs-serialize.ts:569将block_timestamp_type(自不同纪元以来的半秒)转换为ISO格式的日期。参数:名称类型slotnumber返回:stringcheckDateParsecheckDateParse(date: string): number定义于eosjs-serialize.ts:533参数:名称类型datestring返回:numbercheckRangecheckRange(orig: number, converted: number): number定义于eosjs-serialize.ts:765参数:名称类型orignumberconvertednumber返回:numbercreateInitialTypescreateInitialTypes(): Map<string, Type>定义于eosjs-serialize.ts:776创建内置到abi格式的类型集。返回:Map<string, Type>createTypecreateType(attrs: CreateTypeArgs): Type定义于eosjs-serialize.ts:749参数:名称类型attrsCreateTypeArgs返回:TypedateToBlockTimestampdateToBlockTimestamp(date: string): number定义于eosjs-serialize.ts:564将ISO格式的日期转换为block_timestamp_type(自不同纪元以来的半秒)。参数:名称类型datestring返回:numberdateToTimePointdateToTimePoint(date: string): number定义于eosjs-serialize.ts:542将ISO格式的日期转换为time_point(自纪元以来的毫秒数)。参数:名称类型datestring返回:numberdateToTimePointSecdateToTimePointSec(date: string): number定义于eosjs-serialize.ts:553将ISO格式的日期转换为time_point_sec(自纪元以来的秒数)。参数:名称类型datestring返回:numberdeserializeActiondeserializeAction(contract: Contract, account: string, name: string, authorization: Authorization[], data: string | Uint8Array | number[], textEncoder: TextEncoder, textDecoder: TextDecoder): Action定义于eosjs-serialize.ts:1104反序列化操作,如果data是一个string,则假定它是十六进制。参数:名称类型contractContractaccountstringnamestringauthorizationAuthorization[]datastring | Uint8Array | number[]textEncoderTextEncodertextDecoderTextDecoder返回:ActiondeserializeActionDatadeserializeActionData(contract: Contract, account: string, name: string, data: string | Uint8Array | number[], textEncoder: TextEncoder, textDecoder: TextDecoder): any定义于eosjs-serialize.ts:1088反序列化操作数据,如果data是一个string,则假定它是十六进制。参数:名称类型contractContractaccountstringnamestringdatastring | Uint8Array | number[]textEncoderTextEncodertextDecoderTextDecoder返回:anydeserializeArraydeserializeArray(this: Type, buffer: SerialBuffer, state?: SerializerState, allowExtensions?: boolean): any[]定义于eosjs-serialize.ts:700参数:名称类型thisTypebufferSerialBufferOptional stateSerializerStateOptional allowExtensionsboolean返回:any[]deserializeExtensiondeserializeExtension(this: Type, buffer: SerialBuffer, state?: SerializerState, allowExtensions?: boolean): any定义于eosjs-serialize.ts:732参数:名称类型thisTypebufferSerialBufferOptional stateSerializerStateOptional allowExtensionsboolean返回:anydeserializeOptionaldeserializeOptional(this: Type, buffer: SerialBuffer, state?: SerializerState, allowExtensions?: boolean): any定义于eosjs-serialize.ts:719参数:名称类型thisTypebufferSerialBufferOptional stateSerializerStateOptional allowExtensionsboolean返回:anydeserializeStructdeserializeStruct(this: Type, buffer: SerialBuffer, state?: SerializerState, allowExtensions?: boolean): any定义于eosjs-serialize.ts:653参数:名称类型默认值thisType-bufferSerialBuffer-Optional stateSerializerStatenew SerializerState()Optional allowExtensionsbooleantrue返回:anydeserializeUnknowndeserializeUnknown(buffer: SerialBuffer): SerialBuffer定义于eosjs-serialize.ts:624参数:名称类型bufferSerialBuffer返回:SerialBufferdeserializeVariantdeserializeVariant(this: Type, buffer: SerialBuffer, state?: SerializerState, allowExtensions?: boolean): any[]定义于eosjs-serialize.ts:683参数:名称类型thisTypebufferSerialBufferOptional stateSerializerStateOptional allowExtensionsboolean返回:any[]getTypegetType(types: Map<string, Type>, name: string): Type定义于eosjs-serialize.ts:974从types中获取类型。参数:名称类型typesMap<string, Type>namestring返回:TypegetTypesFromAbigetTypesFromAbi(initialTypes: Map<string, Type>, abi: Abi): Map<string, Type>定义于eosjs-serialize.ts:1014从abi获取类型。参数:名称类型描述initialTypesMap<string, Type>要构建的类型集,在大多数情况下,最好通过对getTypesFromAbi()的新调用来填充它abiAbi 返回:Map<string, Type>hexToUint8ArrayhexToUint8Array(hex: string): Uint8Array定义于eosjs-serialize.ts:601将十六进制转换为二进制数据。参数:名称类型hexstring返回:Uint8ArrayserializeActionserializeAction(contract: Contract, account: string, name: string, authorization: Authorization[], data: any, textEncoder: TextEncoder, textDecoder: TextDecoder): SerializedAction定义于eosjs-serialize.ts:1076以序列化形式返回操作。参数:名称类型contractContractaccountstringnamestringauthorizationAuthorization[]dataanytextEncoderTextEncodertextDecoderTextDecoder返回:SerializedActionserializeActionDataserializeActionData(contract: Contract, account: string, name: string, data: any, textEncoder: TextEncoder, textDecoder: TextDecoder): string定义于eosjs-serialize.ts:1064将操作数据转换为序列化形式(十六进制)。参数:名称类型contractContractaccountstringnamestringdataanytextEncoderTextEncodertextDecoderTextDecoder返回:stringserializeArrayserializeArray(this: Type, buffer: SerialBuffer, data: any[], state?: SerializerState, allowExtensions?: boolean): void定义于eosjs-serialize.ts:692参数:名称类型thisTypebufferSerialBufferdataany[]Optional stateSerializerStateOptional allowExtensionsboolean返回:voidserializeExtensionserializeExtension(this: Type, buffer: SerialBuffer, data: any, state?: SerializerState, allowExtensions?: boolean): void定义于eosjs-serialize.ts:727参数:名称类型thisTypebufferSerialBufferdataanyOptional stateSerializerStateOptional allowExtensionsboolean返回:voidserializeOptionalserializeOptional(this: Type, buffer: SerialBuffer, data: any, state?: SerializerState, allowExtensions?: boolean): void定义于eosjs-serialize.ts:709参数:名称类型thisTypebufferSerialBufferdataanyOptional stateSerializerStateOptional allowExtensionsboolean返回:voidserializeStructserializeStruct(this: Type, buffer: SerialBuffer, data: any, state?: SerializerState, allowExtensions?: boolean): void定义于eosjs-serialize.ts:628参数:名称类型默认值thisType-bufferSerialBuffer-dataany-Optional stateSerializerStatenew SerializerState()Optional allowExtensionsbooleantrue返回:voidserializeUnknownserializeUnknown(buffer: SerialBuffer, data: any): SerialBuffer定义于eosjs-serialize.ts:620参数:名称类型bufferSerialBufferdataany返回:SerialBufferserializeVariantserializeVariant(this: Type, buffer: SerialBuffer, data: any, state?: SerializerState, allowExtensions?: boolean): void定义于eosjs-serialize.ts:670参数:名称类型thisTypebufferSerialBufferdataanyOptional stateSerializerStateOptional allowExtensionsboolean返回:voidstringToSymbolstringToSymbol(s: string): object定义于eosjs-serialize.ts:575将string转换为Symbol,格式:precision,NAME。参数:名称类型sstring返回:objectsupportedAbiVersionsupportedAbiVersion(version: string): boolean定义于eosjs-serialize.ts:529这是受支持的ABI版本吗?参数:名称类型versionstring返回:booleansymbolToStringsymbolToString(__namedParameters: object): string定义于eosjs-serialize.ts:587将Symbol转换为string,格式:precision,NAME。参数:__namedParameters:object名称类型namestringprecisionnumber返回:stringtimePointSecToDatetimePointSecToDate(sec: number): string定义于eosjs-serialize.ts:558将time_point_sec(自纪元以来的秒数)转换为ISO格式的日期。参数:名称类型secnumber返回:stringtimePointToDatetimePointToDate(us: number): string定义于eosjs-serialize.ts:547将time_point(自纪元以来的毫秒数)转换为ISO格式的日期。参数:名称类型usnumber返回:stringtransactionHeadertransactionHeader(refBlock: BlockTaposInfo, expireSeconds: number): object定义于eosjs-serialize.ts:1055TAPoS:返回引用refBlock的交易字段,并在refBlock.timestamp之后expireSeconds到期。参数:名称类型refBlockBlockTaposInfoexpireSecondsnumber返回:object上一篇:RPC接口 ...

January 4, 2019 · 2 min · jiezi

eosjs 文档(RPC接口)

RPC接口接口AbiBlockTaposInfoGetAbiResultGetBlockResultGetCodeResultGetInfoResultGetRawCodeAndAbiResultPushTransactionArgsAbi属性abi_extensions:Array<object>定义于eosjs-rpc-interfaces.ts:15actions:Array<object>定义于eosjs-rpc-interfaces.ts:11error_messages:Array<object>定义于eosjs-rpc-interfaces.ts:14ricardian_clauses:Array<object>定义于eosjs-rpc-interfaces.ts:13structs:Array<object>定义于eosjs-rpc-interfaces.ts:10tables:Array<object>定义于eosjs-rpc-interfaces.ts:12types:Array<object>定义于eosjs-rpc-interfaces.ts:9<Optional> variants:Array<object>定义于eosjs-rpc-interfaces.ts:16version:string定义于eosjs-rpc-interfaces.ts:8BlockTaposInfo属性block_num:number定义于eosjs-rpc-interfaces.ts:28ref_block_prefix:number定义于eosjs-rpc-interfaces.ts:29timestamp:string定义于eosjs-rpc-interfaces.ts:27GetAbiResult属性abi:Abi定义于eosjs-rpc-interfaces.ts:22account_name:string定义于eosjs-rpc-interfaces.ts:21GetBlockResult属性action_mroot:string定义于eosjs-rpc-interfaces.ts:39block_num:number定义于eosjs-rpc-interfaces.ts:43confirmed:number定义于eosjs-rpc-interfaces.ts:36id:string定义于eosjs-rpc-interfaces.ts:42previous:string定义于eosjs-rpc-interfaces.ts:37producer:string定义于eosjs-rpc-interfaces.ts:35producer_signature:string定义于eosjs-rpc-interfaces.ts:41ref_block_prefix:number定义于eosjs-rpc-interfaces.ts:44schedule_version:number定义于eosjs-rpc-interfaces.ts:40timestamp:string定义于eosjs-rpc-interfaces.ts:34transaction_mroot:string定义于eosjs-rpc-interfaces.ts:38GetCodeResult属性abi:Abi定义于eosjs-rpc-interfaces.ts:53account_name:string定义于eosjs-rpc-interfaces.ts:49code_hash:string定义于eosjs-rpc-interfaces.ts:50wasm:string定义于eosjs-rpc-interfaces.ts:52wast:string定义于eosjs-rpc-interfaces.ts:51GetInfoResult属性block_cpu_limit:number定义于eosjs-rpc-interfaces.ts:68block_net_limit:number定义于eosjs-rpc-interfaces.ts:69chain_id:string定义于eosjs-rpc-interfaces.ts:59head_block_id:string定义于eosjs-rpc-interfaces.ts:63head_block_num:number定义于eosjs-rpc-interfaces.ts:60head_block_producer:string定义于eosjs-rpc-interfaces.ts:65head_block_time:string定义于eosjs-rpc-interfaces.ts:64last_irreversible_block_id:string定义于eosjs-rpc-interfaces.ts:62last_irreversible_block_num:number定义于eosjs-rpc-interfaces.ts:61server_version:string定义于eosjs-rpc-interfaces.ts:58virtual_block_cpu_limit:number定义于eosjs-rpc-interfaces.ts:66virtual_block_net_limit:number定义于eosjs-rpc-interfaces.ts:67GetRawCodeAndAbiResult属性abi:string定义于eosjs-rpc-interfaces.ts:76account_name:string定义于eosjs-rpc-interfaces.ts:74wasm:string定义于eosjs-rpc-interfaces.ts:75PushTransactionArgs属性serializedTransaction:Uint8Array定义于eosjs-rpc-interfaces.ts:82signatures:string[]定义于eosjs-rpc-interfaces.ts:81上一篇:RPC-Error

January 3, 2019 · 1 min · jiezi

eosjs 文档(RPC-Error)

RPC-Error类RpcErrorRpcError构造函数new RpcError(json: any): RpcError定义于eosjs-rpcerror.ts:9参数:名称类型jsonany返回:RpcError属性jsonjson:any定义于eosjs-rpcerror.ts:9详细的错误信息。messagemessage:string继承自Error.message。namename:string继承自Error.name。<Optional> stackstack:string继承自Error.stack,重写Error.stack。<Static> ErrorError:ErrorConstructor上一篇:Numeric

January 3, 2019 · 1 min · jiezi

eosjs 文档(Numeric)

Numeric枚举KeyType接口Key变量base58Charsbase58Mapbase64Charsbase64MapprivateKeyDataSizepublicKeyDataSizeripemd160signatureDataSize函数base58ToBinarybase64ToBinarybinaryToBase58binaryToDecimalconvertLegacyPublicKeyconvertLegacyPublicKeyscreate_base58_mapcreate_base64_mapdecimalToBinarydigestSuffixRipemd160isNegativekeyToStringnegateprivateKeyToStringpublicKeyToStringsignatureToStringsignedBinaryToDecimalsignedDecimalToBinarystringToKeystringToPrivateKeystringToPublicKeystringToSignature变量<Const> base58Charsconst base58Chars = “123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz”;定义于eosjs-numeric.ts:9<Const> base58Mapconst base58Map = create_base58_map();定义于eosjs-numeric.ts:20<Const> base64Charsconst base64Chars = “ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";定义于eosjs-numeric.ts:10<Const> base64Mapconst base64Map = create_base64_map();定义于eosjs-numeric.ts:31<Const> privateKeyDataSizeexport const privateKeyDataSize = 32;定义于eosjs-numeric.ts:227私钥数据大小,不包括类型字段。<Const> publicKeyDataSizeexport const publicKeyDataSize = 33;定义于eosjs-numeric.ts:224公钥数据大小,不包括类型字段。<Const> ripemd160const ripemd160 = require(”./ripemd").RIPEMD160.hash as (a: Uint8Array) => ArrayBuffer;定义于eosjs-numeric.ts:7类型声明(a: Uint8Array): ArrayBuffer参数:名称类型aUint8Array返回:ArrayBuffer<Const> signatureDataSizeexport const signatureDataSize = 65;定义于eosjs-numeric.ts:230签名数据大小,不包括类型字段。函数base58ToBinarybase58ToBinary(size: number, s: string): Uint8Array定义于eosjs-numeric.ts:132将s中的无符号base-58数转换为bignum。参数:名称类型描述sizenumberbignum大小(字节)sstring 返回:Uint8Arraybase64ToBinarybase64ToBinary(s: string): Uint8Array定义于eosjs-numeric.ts:182将s中的无符号base-64数转换为bignum。参数:名称类型sstring返回:Uint8ArraybinaryToBase58binaryToBase58(bignum: Uint8Array, minDigits?: number): string定义于eosjs-numeric.ts:156将bignum转换为base-58的数。参数:名称类型默认值描述bignumUint8Array- Default value minDigitsnumber10填充的结果是许多数字返回:stringbinaryToDecimalbinaryToDecimal(bignum: Uint8Array, minDigits?: number): string定义于eosjs-numeric.ts:97将bignum转换为无符号十进制数。参数:名称类型默认值描述bignumUint8Array- Default value minDigitsnumber10填充的结果是许多数字返回:stringconvertLegacyPublicKeyconvertLegacyPublicKey(s: string): string定义于eosjs-numeric.ts:312如果密钥是旧格式(EOS前缀),则将其转换为新格式(PUB_K1_),保持其他格式不变。参数:名称类型sstring返回:stringconvertLegacyPublicKeysconvertLegacyPublicKeys(keys: string[]): string[]定义于eosjs-numeric.ts:322如果密钥是旧格式(EOS前缀),则将其转换为新格式(PUB_K1_),保持其他格式不变。参数:名称类型keysstring[]返回:string[]create_base58_mapcreate_base58_map(): number[]定义于eosjs-numeric.ts:12返回:number[]create_base64_mapcreate_base64_map(): number[]定义于eosjs-numeric.ts:22返回:number[]decimalToBinarydecimalToBinary(size: number, s: string): Uint8Array定义于eosjs-numeric.ts:52将s中的无符号十进制数转换为bignum。参数:名称类型描述sizenumberbignum大小(字节)sstring 返回:Uint8ArraydigestSuffixRipemd160digestSuffixRipemd160(data: Uint8Array, suffix: string): ArrayBuffer定义于eosjs-numeric.ts:238参数:名称类型dataUint8Arraysuffixstring返回:ArrayBufferisNegativeisNegative(bignum: Uint8Array): boolean定义于eosjs-numeric.ts:34bignum是负数吗?参数:名称类型bignumUint8Array返回:booleankeyToStringkeyToString(key: Key, suffix: string, prefix: string): string定义于eosjs-numeric.ts:260参数:名称类型keyKeysuffixstringprefixstring返回:stringnegatenegate(bignum: Uint8Array): void定义于eosjs-numeric.ts:39bignum转为负数。参数:名称类型bignumUint8Array返回:voidprivateKeyToStringprivateKeyToString(key: Key): string定义于eosjs-numeric.ts:339将key转换为字符串(base-58)形式。参数:名称类型keyKey返回:stringpublicKeyToStringpublicKeyToString(key: Key): string定义于eosjs-numeric.ts:299将key转换为字符串(base-58)形式。参数:名称类型keyKey返回:stringsignatureToStringsignatureToString(signature: Key): string定义于eosjs-numeric.ts:362将signature转换为字符串(base-58)形式。参数:名称类型signatureKey返回:stringsignedBinaryToDecimalsignedBinaryToDecimal(bignum: Uint8Array, minDigits?: number): string定义于eosjs-numeric.ts:119将bignum转换为带符号的十进制数。参数:名称类型默认值描述bignumUint8Array- Default value minDigitsnumber10填充的结果是许多数字返回:stringsignedDecimalToBinarysignedDecimalToBinary(size: number, s: string): Uint8Array定义于eosjs-numeric.ts:76将s中的带符号十进制数转换为bignum。参数:名称类型描述sizenumberbignum大小(字节)sstring 返回:Uint8ArraystringToKeystringToKey(s: string, type: KeyType, size: number, suffix: string): Key定义于eosjs-numeric.ts:249参数:名称类型sstringtypeKeyTypesizenumbersuffixstring返回:KeystringToPrivateKeystringToPrivateKey(s: string): Key定义于eosjs-numeric.ts:327将s中的密钥转换为二进制形式。参数:名称类型sstring返回:KeystringToPublicKeystringToPublicKey(s: string): Key定义于eosjs-numeric.ts:273将s中的密钥转换为二进制形式。参数:名称类型sstring返回:KeystringToSignaturestringToSignature(s: string): Key定义于eosjs-numeric.ts:348将s中的密钥转换为二进制形式。参数:名称类型sstring返回:KeyKeyType枚举成员k1k1:= 0定义于eosjs-numeric.ts:219r1r1:= 1定义于eosjs-numeric.ts:220Key属性datadata:Uint8Array定义于eosjs-numeric.ts:235typetype:KeyType定义于eosjs-numeric.ts:234上一篇:JSON-RPC ...

January 3, 2019 · 1 min · jiezi

eosjs 文档(JSON-RPC)

JSON-RPC类JsonRpc函数arrayToHex函数arrayToHexarrayToHex(data: Uint8Array): string定义于eosjs-jsonrpc.ts:11参数:名称类型dataUint8Array返回:stringJsonRpc实现接口AuthorityProviderAbiProvider构造函数new JsonRpc(endpoint: string, args?: object): JsonRpc定义于eosjs-jsonrpc.ts:22参数:endpoint:stringDefault value args:objectfetch:浏览器:保留null或undefinednode:提供实现名称类型(可选的)fetchfunction返回:JsonRpc属性endpointendpoint:string定义于eosjs-jsonrpc.ts:21fetchBuiltinfetchBuiltin:function定义于eosjs-jsonrpc.ts:22类型声明(input?: Request | string, init?: RequestInit): Promise<Response>参数:名称类型(可选的)inputRequest | string(可选的)initRequestInit返回:Promise<Response>方法db_size_getdb_size_get(): Promise<any>定义于eosjs-jsonrpc.ts:182原始调用/v1/db_size/get返回:Promise<any>fetchfetch(path: string, body: any): Promise<any>定义于eosjs-jsonrpc.ts:42发布body到endpoint + path,在可用时在RpcError中抛出详细的错误信息。参数:名称类型pathstringbodyany返回:Promise<any>getRawAbigetRawAbi(accountName: string): Promise<BinaryAbi>定义于eosjs-jsonrpc.ts:129调用/v1/chain/get_raw_code_and_abi并提取不需要的原始wasm代码。参数:名称类型accountNamestring返回:Promise<BinaryAbi>getRequiredKeysgetRequiredKeys(args: AuthorityProviderArgs): Promise<string[]>定义于eosjs-jsonrpc.ts:164获取满足transaction权限所需的availableKeys子集,实现AuthorityProvider。参数:名称类型argsAuthorityProviderArgs返回:Promise<string[]>get_abiget_abi(account_name: string): Promise<GetAbiResult>定义于eosjs-jsonrpc.ts:67原始调用/v1/chain/get_abi参数:名称类型account_namestring返回:Promise<GetAbiResult>get_accountget_account(account_name: string): Promise<any>定义于eosjs-jsonrpc.ts:73原始调用/v1/chain/get_account参数:名称类型account_namestring返回:Promise<any>get_blockget_block(block_num_or_id: number | string): Promise<GetBlockResult>定义于eosjs-jsonrpc.ts:85原始调用/v1/chain/get_block参数:名称类型block_num_or_idnumber | string返回:Promise<GetBlockResult>get_block_header_stateget_block_header_state(block_num_or_id: number | string): Promise<any>定义于eosjs-jsonrpc.ts:79原始调用/v1/chain/get_block_header_state参数:名称类型block_num_or_idnumber | string返回:Promise<any>get_codeget_code(account_name: string): Promise<GetCodeResult>定义于eosjs-jsonrpc.ts:91原始调用/v1/chain/get_code参数:名称类型account_namestring返回:Promise<GetCodeResult>get_currency_balanceget_currency_balance(code: string, account: string, symbol?: string): Promise<any>定义于eosjs-jsonrpc.ts:96原始调用/v1/chain/get_currency_balance参数:名称类型默认值codestring-accountstring-Default value symbolstringnull返回:Promise<any>get_currency_statsget_currency_stats(code: string, symbol: string): Promise<any>定义于eosjs-jsonrpc.ts:101原始调用/v1/chain/get_currency_stats参数:名称类型codestringsymbolstring返回:Promise<any>get_infoget_info(): Promise<GetInfoResult>定义于eosjs-jsonrpc.ts:106原始调用/v1/chain/get_info返回:Promise<GetInfoResult>get_producer_scheduleget_producer_schedule(): Promise<any>定义于eosjs-jsonrpc.ts:111原始调用/v1/chain/get_producer_schedule返回:Promise<any>get_producersget_producers(json?: boolean, lower_bound?: string, limit?: number): Promise<any>定义于eosjs-jsonrpc.ts:117原始调用/v1/chain/get_producers参数:名称类型默认值Default value jsonbooleantrueDefault value lower_boundstring"“Default value limitnumber50返回:Promise<any>get_raw_code_and_abiget_raw_code_and_abi(account_name: string): Promise<GetRawCodeAndAbiResult>定义于eosjs-jsonrpc.ts:123原始调用/v1/chain/get_raw_code_and_abi参数:名称类型account_namestring返回:Promise<GetRawCodeAndAbiResult>get_table_rowsget_table_rows(__namedParameters: object): Promise<any>定义于eosjs-jsonrpc.ts:136原始调用/v1/chain/get_table_rows参数:__namedParameters:object名称类型默认值codeany-index_positionany1jsonanytruekey_typeany"“limitany10lower_boundany"“scopeany-tableany-table_keyany"“upper_boundany"“返回:Promise<any>history_get_actionshistory_get_actions(account_name: string, pos?: number, offset?: number): Promise<any>定义于eosjs-jsonrpc.ts:186原始调用/v1/history/get_actions参数:名称类型默认值account_namestring-Default value posnumbernullDefault value offsetnumbernull返回:Promise<any>history_get_controlled_accountshistory_get_controlled_accounts(controlling_account: string): Promise<any>定义于eosjs-jsonrpc.ts:204原始调用/v1/history/get_controlled_accounts参数:名称类型controlling_accountstring返回:Promise<any>history_get_key_accountshistory_get_key_accounts(public_key: string): Promise<any>定义于eosjs-jsonrpc.ts:198原始调用/v1/history/get_key_accounts参数:名称类型public_keystring返回:Promise<any>history_get_transactionhistory_get_transaction(id: string, block_num_hint?: number): Promise<any>定义于eosjs-jsonrpc.ts:192原始调用/v1/history/get_transaction参数:名称类型默认值idUint8Array-Default value block_num_hintnumbernull返回:Promise<any>push_transactionpush_transaction(__namedParameters: object): Promise<any>定义于eosjs-jsonrpc.ts:172推送序列化交易。参数:__namedParameters:object名称类型serializedTransactionUint8Arraysignaturesstring[]返回:Promise<any>上一篇:JS-Sig ...

January 3, 2019 · 1 min · jiezi

eosjs 文档(JS-Sig)

JS-SigJsSignatureProviderJsSignatureProvider实现接口SignatureProvider构造函数new JsSignatureProvider(privateKeys: string[]): JsSignatureProvider定义于eosjs-jssig.ts:16参数:名称类型描述privateKeysstring[]用于签名的私钥返回:JsSignatureProvider属性availableKeysavailableKeys:string[] = [] as string[]定义于eosjs-jssig.ts:16公钥。keyskeys:Map<string, string> = new Map()定义于eosjs-jssig.ts:13将公钥映射到私钥。方法getAvailableKeysgetAvailableKeys(): Promise<string[]>定义于eosjs-jssig.ts:28与SignatureProvider保存的私钥关联的公钥。返回:Promise<string[]>signsign(__namedParameters: object): Promise<object>定义于eosjs-jssig.ts:33签名交易。参数:__namedParameters:object名称类型chainIdstringrequiredKeysstring[]serializedTransactionUint8Array返回:Promise<object>上一篇:API接口

January 2, 2019 · 1 min · jiezi

eosjs 文档(API接口)

API接口AbiProvider实现类JsonRpc属性getRawAbigetRawAbi:function定义于eosjs-api-interfaces.ts:26检索BinaryAbi。类型声明(accountName: string): Promise<BinaryAbi>参数:名称类型accountNamestring返回:Promise<BinaryAbi>AuthorityProvider实现类JsonRpc属性getRequiredKeysgetRequiredKeys:function定义于eosjs-api-interfaces.ts:20获取满足transaction权限所需的availableKeys子集。类型声明(args: AuthorityProviderArgs): Promise<string[]>参数:名称类型argsAuthorityProviderArgs返回:Promise<string[]>AuthorityProviderArgs属性availableKeysavailableKeys:string[]定义于eosjs-api-interfaces.ts:14与SignatureProvider保存的私钥关联的公钥。transactiontransaction:any定义于eosjs-api-interfaces.ts:11需要签名的交易。BinaryAbi属性abiabi:Uint8Array定义于eosjs-api-interfaces.ts:36二进制形式的abi。accountNameaccountName:string定义于eosjs-api-interfaces.ts:33已部署ABI的帐户。CachedAbi属性abiabi:Abi定义于eosjs-api-interfaces.ts:45结构化形式的abi。rawAbirawAbi:Uint8Array定义于eosjs-api-interfaces.ts:42二进制形式的abi。SignatureProvider实现类JsSignatureProvider属性getAvailableKeysgetAvailableKeys:function定义于eosjs-api-interfaces.ts:66与SignatureProvider保存的私钥关联的公钥。类型声明(): Promise<string[]>返回:Promise<string[]>signsign:function定义于eosjs-api-interfaces.ts:69签名交易。类型声明(args: SignatureProviderArgs): Promise<PushTransactionArgs>参数:名称类型argsSignatureProviderArgs返回:Promise<PushTransactionArgs>SignatureProviderArgs属性abisabis:BinaryAbi[]定义于eosjs-api-interfaces.ts:60操作包含在serializedTransaction中的所有合约的ABI。chainIdchainId:string定义于eosjs-api-interfaces.ts:51用于交易的链。requiredKeysrequiredKeys:string[]定义于eosjs-api-interfaces.ts:54与签名交易所需的私钥相关联的公钥。serializedTransactionserializedTransaction:Uint8Array定义于eosjs-api-interfaces.ts:57要签名的交易。上一篇:API

January 2, 2019 · 1 min · jiezi

eosjs 文档(API)

API索引类Api变量abiAbitransactionAbi变量<Const> abiAbiabiAbi:any = require(’../src/abi.abi.json’)定义于eosjs-api.ts:12<Const> transactionAbitransactionAbi:any = require(’../src/transaction.abi.json’)定义于eosjs-api.ts:14构造函数new Api(args: object): Api定义于eosjs-api.ts:45参数:args: objectrpc:发出RPC调用authorityProvider:获取在交易中满足权限所需的公钥abiProvider:以原始形式供应ABI(二进制)signatureProvider:签名交易chainId:标识链textEncoder:要使用的TextEncoder实例,如果在浏览器中运行,则传入nulltextDecoder:要使用的TextDecoder实例,如果在浏览器中运行,则传入null名称类型(可选的)abiProviderAbiProvider(可选的)authorityProviderAuthorityProvider(可选的)chainIdstringrpcJsonRpcsignatureProviderSignatureProvider(可选的)textDecoderTextDecoder(可选的)textEncoderTextEncoder返回:Api属性abiProviderabiProvider:AbiProvider定义于eosjs-api.ts:24以原始形式供应ABI(二进制)abiTypesabiTypes:Map<string, ser.Type>定义于eosjs-api.ts:36在二进制和结构化形式之间转换abi文件(abi.abi.json)authorityProviderauthorityProvider:AuthorityProvider定义于eosjs-api.ts:21获取满足transaction权限所需的availableKeys子集cachedAbiscachedAbis:Map<string, CachedAbi> = new Map()定义于eosjs-api.ts:45提取abichainIdchainId:string定义于eosjs-api.ts:30标识链contractscontracts:Map<string, Contract> = new Map()定义于eosjs-api.ts:42保存序列化合约操作所需的信息rpcrpc:JsonRpc定义于eosjs-api.ts:18发出RPC调用signatureProvidersignatureProvider:SignatureProvider定义于eosjs-api.ts:27签名交易textDecodertextDecoder:TextDecoder定义于eosjs-api.ts:33textEncodertextEncoder:TextEncoder定义于eosjs-api.ts:32transactionTypestransactionTypes:Map<string, ser.Type>定义于eosjs-api.ts:39在二进制和结构化形式之间转换交易(transaction.abi.json)方法deserializedeserialize(buffer: ser.SerialBuffer, type: string): any定义于eosjs-api.ts:151将buffer中的数据转换为结构化形式,type必须是内置的abi类型或者在transaction.abi.json中。参数:名称类型bufferser.SerialBuffertypestring返回:anydeserializeActionsdeserializeActions(actions: ser.Action[]): Promise<ser.Action[]>定义于eosjs-api.ts:187从十六进制转换操作参数:名称类型actionsser.Action[]返回:Promise<ser.Action[]>deserializeTransactiondeserializeTransaction(transaction: Uint8Array): any定义于eosjs-api.ts:171从二进制转换交易,将操作保留为十六进制参数:名称类型transactionUint8Array返回:anydeserializeTransactionWithActionsdeserializeTransactionWithActions(transaction: Uint8Array | string): Promise<any>定义于eosjs-api.ts:196从二进制转换交易,同时反序列化操作参数:名称类型transactionUint8Array | string返回:Promise<any>getAbigetAbi(accountName: string, reload?: boolean): Promise<Abi>定义于eosjs-api.ts:114以结构化形式获取abi,需要时提取参数:名称类型默认值accountNamestring-Default value reloadbooleanfalse返回:Promise<Abi>getCachedAbigetCachedAbi(accountName: string, reload?: boolean): Promise<CachedAbi>定义于eosjs-api.ts:93以二进制和结构化形式获取abi,需要时提取参数:名称类型默认值accountNamestring-Default value reloadbooleanfalse返回:Promise<CachedAbi>getContractgetContract(accountName: string, reload?: boolean): Promise<ser.Contract>定义于eosjs-api.ts:130获取序列化合约中的操作所需的数据参数:名称类型默认值accountNamestring-Default value reloadbooleanfalse返回:Promise<ser.Contract>getTransactionAbisgetTransactionAbis(transaction: any, reload?: boolean): Promise<BinaryAbi[]>定义于eosjs-api.ts:119获取交易所需的abi参数:名称类型默认值transactionany-Default value reloadbooleanfalse返回:Promise<BinaryAbi[]>pushSignedTransactionpushSignedTransaction(__namedParameters: object): Promise<any>定义于eosjs-api.ts:259广播已签名的交易__namedParameters:object名称类型serializedTransactionUint8Arraysignaturesstring[]返回:Promise<any>rawAbiToJsonrawAbiToJson(rawAbi: Uint8Array): Abi定义于eosjs-api.ts:79将abi作为Uint8Array解码为json参数:名称类型rawAbiUint8Array返回:Abiserializeserialize(buffer: ser.SerialBuffer, type: string, value: any): void定义于eosjs-api.ts:146将value转换为二进制形式,type必须是内置的abi类型或者在transaction.abi.json中。参数:名称类型bufferser.SerialBuffertypestringvalueany返回:voidserializeActionsserializeActions(actions: ser.Action[]): Promise<ser.SerializedAction[]>定义于eosjs-api.ts:178将操作转换为十六进制参数:名称类型actionsser.Action[]返回:Promise<ser.SerializedAction[]>serializeTransactionserializeTransaction(transaction: any): Uint8Array定义于eosjs-api.ts:156将交易转换为二进制参数:名称类型transactionany返回:Uint8Arraytransacttransact(transaction: any, __namedParameters?: object): Promise<any>定义于eosjs-api.ts:216创建并可选择广播交易命名参数:broadcast:广播此交易?sign:签名此交易?如果blocksBehind和expireSeconds都存在,然后提取块头后面的blockBehind块,将其用作TAPoS的引用,并在该块的时间expireSeconds之后过期交易。参数:transaction:anyDefault value __namedParameters:object名称类型默认值blocksBehindnumber-broadcastbooleantrueexpireSecondsnumber-signbooleantrue返回:如果broadcast,则Promise<any>节点响应,如果!broadcast 则{signatures, serializedTransaction}。上一篇:读取区块链 ...

January 2, 2019 · 1 min · jiezi

理解eosio.token合约

我必须承认,学习eosio一直没有闲庭信步的感觉,我可以看到为什么很多人说它有一个陡峭的学习曲线。随着eosio软件继续经历大量快速发展,文档数量有限,很少有工作实例可供参考。我已经被困了好几次,也希望帮助改善下一个开发人员的体验。在本文中,我将通过将其分解为单独的部分来讨论eosio.token合约。什么是eosio.token合约?eosio.token合约允许创建许多不同的代币。这使任何人都能够创建和发送代币。每个代币必须由issuer帐户发行。由于帐户可以包含多方,因此你可以使用具有所有者和活动权限的普通帐户或自定义配置帐户来创建和管理代币。每个代币都是asset类型,如下所示:1000000000.0000 SYS1.0000 SYMBOL0.10 SYSasset类型是一个数字(如果我没记错的话可以达到18位小数)和一个可以在1-7个大写字母之间的符号。此合约有三个操作可用于与之交互。它们是:创建,发布和转账。创建用于定义新代币的特征。这包括代币asset符号,最大供应量以及允许发出代币的帐户。创建还会将新代币配置保留在区块链上。这意味着新代币配置的存储必须由某人放置。正如你稍后将看到的,部署此合约的帐户(在我们的案例中为’eosio.token’)也将支付代币配置存储。发布用于增加代币的有效供应。可以持续发出代币,直到达到最大供应量。在代币创建期间定义的issuer必须批准此操作才能使其成功。转账让一个帐户将代币转移到另一个帐户。部署合约你应该知道的第一件事是每个eosio智能合约都属于一个eosio帐户。合约基本上是其他帐户可以与之交互的对象。合约包含在区块链上执行代码的操作actions。合约可以直接访问区块链上的存储,删除和更新数据。将一个action推送到合约需要至少一个帐户的授权。根据合约的复杂性,可能需要进一步的帐户和权限。帐户可以由基于权限的配置中设置的单个或多个个人组成。智能合约只能由一个帐户运行,而一个帐户只能拥有一个智能合约。最佳做法是为帐户和合约提供相同(小写)的名称。在你与eosio.token合约进行交互之前,你需要创建一个具有相同名称的帐户,并将合约部署到该帐户。首先创建一个帐户$cleos create account eosio eosio.token <OWNER-KEY> <ACTIVE-KEY>然后编译合约$cd eos/contract/eosio.token$eosiocpp -o eosio.token.wast eosio.token.cpp最后将合约部署到帐户上$cleos set contract eosio.token ../eosio.token你可以验证合约是否已部署$cleos get code eosio.token合约架构合约分为两个文件eosio.token.cpp和eosio.token.hpp。.hpp文件定义合约类,操作和表,而.cpp文件实现操作逻辑。让我们首先看一下将用于实例化合约对象的合约类。(我从eosio.token.hpp中删除了一些遗留代码)/** * @file * @copyright defined in eos/LICENSE.txt /#pragma once#include <eosiolib/asset.hpp>#include <eosiolib/eosio.hpp>#include <string>namespace eosiosystem { class system_contract;}namespace eosio { using std::string; class token : public contract { public: token( account_name self ):contract(self){} void create( account_name issuer, asset maximum_supply); void issue( account_name to, asset quantity, string memo ); void transfer( account_name from, account_name to, asset quantity, string memo ); private: friend eosiosystem::system_contract; inline asset get_supply( symbol_name sym )const; inline asset get_balance( account_name owner, symbol_name sym )const; struct account { asset balance; uint64_t primary_key()const { return balance.symbol.name(); } }; struct currency_stats { asset supply; asset max_supply; account_name issuer; uint64_t primary_key()const { return supply.symbol.name(); } }; typedef eosio::multi_index<N(accounts), account> accounts; typedef eosio::multi_index<N(stat), currency_stats> stats; void sub_balance( account_name owner, asset value ); void add_balance( account_name owner, asset value, account_name ram_payer ); }; asset token::get_supply( symbol_name sym )const { stats statstable( _self, sym ); const auto& st = statstable.get( sym ); return st.supply; } asset token::get_balance( account_name owner, symbol_name sym )const { accounts accountstable( _self, owner ); const auto& ac = accountstable.get( sym ); return ac.balance; }} /// namespace eosio构造函数和操作被定义为公共成员函数。构造函数采用帐户名称(将是部署合约的帐户,也就是eosio.token)并将其设置为contract变量。请注意,此类继承自eosio::contract。表和helper函数作为私有成员提供。两个内联函数在底部定义但从未使用过。这给我们留下了重要的函数sub_balance()和add_balance()。这些将由转移操作调用。表定义的两个表是accounts和stat。accounts表由不同的account对象组成,每个account对象持有不同代币的余额。stat表由持有供应,max_supply和发行者的currency_stats对象(由struct currency_stats定义)组成。在继续之前,重要的是要知道该合约将数据保存到两个不同的范围。accounts表的范围限定为eosio帐户,stat表的范围限定为代币符号名称。根据eosio::multi_index定义,code是具有写权限的帐户的名称,scope是存储数据的帐户。范围本质上是一种在合约中划分数据的方法,以便只能在定义的空间内访问。在代币合约中,每个eosio帐户都用作accounts表的范围。accounts表是一个包含多个account对象的多索引容器。每个account对象都由其代币符号编制索引,并包含代币余额。使用其范围查询用户的accounts表时,将返回用户具有现有余额的所有代币的列表。这是我如何想象它。在上图中,有一个名为tom的eosio帐户,他有自己的范围。在他的范围内是一个名为accounts的表。在该表中是一个单独的account对象,用于他持有的每个代币,SYS和EOS。还有一个名为stat的第二个表。此表将包含现有代币的状态。新标记在其自己的符号名称范围内创建。范围内是一个包含currency_stats对象的stat表。与包含许多不同account对象的accounts表不同,stat表仅包含给定标记符号的单个currency_stats对象。操作操作在.cpp文件中实现。要创建新代币,必须发送创建操作。Create有两个参数:发行者,以及新代币的最大供应量。issuer是唯一允许增加新代币供应的人。issuer不能超过最高供应量发行。第一行代码只需要合约帐户本身的授权。这可以在推动操作时使用命令行标志-p eosio.token给出。接下来的几行提取传入的maximum_supply资产的符号并执行一些错误处理。如果任何eosio_assert失败,那么所有代码都将被回滚,并且交易不会被推送到区块链。一个stat表使用符号名称(标记符号)作为其范围构造为statstable。代码检查代币是否已存在。如果没有,则创建新代币状态并将其保存到区块链中。emplace函数中的第一个参数_self意味着此合约帐户eosio.token将支付投注存储。请注意,保存supply的符号,因为它用作定位表行的键,但供应量尚未发出。你现在可以执行下一个操作,发布。发布将采用将收到已发行代币的帐户,发出的代币数量和备忘录。发布操作在一个中执行两个操作,因为它将修改创建的代币供应并调用转账操作以发送已发布的代币。同样,前几行提取代币符号并执行错误检查。以下代码部分将使用符号名称作为范围构造stat表。这用作查找先前使用create action创建的代币的键。请注意,从statstable.find()返回的existing currency_stat是一个指向找到的对象的迭代器。为简洁起见,声明了一个名为st的新变量,并将其设置为existing迭代器指向的实际对象。这让我们可以使用.运算符访问成员变量而不是指针表示法->。创建代币的issuer者需要签署此交易,并执行更多错误处理。最后,修改现有代币的currency_stats st,并将已发放的quantity添加到supply。issuer也将此supply添加到他们的余额中,以便初始供应可以追溯到他们的帐户。紧接着,通过SEND_INLINE_ACTION()调用transfer函数,这会将资金进行转移。论点如下:1.this是行动所属的合约代码。2.transfer操作的名称。3.{st.issuer, N(active)}操作所需的权限。4.{st.issuer, to, quantity, memo}操作本身的参数。这将我们带到最后的转账操作。转账操作将从from,to,quantity和memo获取四个输入参数。from是谁将发送代币,因此quantity将从他们的余额中减去。to是谁将收到代币,因此quantity将被添加到他们的余额。quantity是要发送的代币数量,memo是一个可以与交易一起发送的字符串。memo未在本合约中使用或存储。该操作首先要求from accounts帐户权限并对from和to帐户执行发布处理。该符号从quantity提取并用于获取代币的currency_stats。require_recipient()函数将在操作完成时通知发送方和接收方。完成更多发布处理,最后调用两个私有函数sub_balance()和add_balance()以从发送add_balance()减去代币余额并增加接收方的代币余额。这是完整的’eosio.token.cpp’文件。/ * @file * @copyright defined in eos/LICENSE.txt */#include “eosio.token.hpp"namespace eosio {void token::create( account_name issuer, asset maximum_supply ){ require_auth( _self ); auto sym = maximum_supply.symbol; eosio_assert( sym.is_valid(), “invalid symbol name” ); eosio_assert( maximum_supply.is_valid(), “invalid supply”); eosio_assert( maximum_supply.amount > 0, “max-supply must be positive”); stats statstable( _self, sym.name() ); auto existing = statstable.find( sym.name() ); eosio_assert( existing == statstable.end(), “token with symbol already exists” ); statstable.emplace( _self, [&]( auto& s ) { s.supply.symbol = maximum_supply.symbol; s.max_supply = maximum_supply; s.issuer = issuer; });}void token::issue( account_name to, asset quantity, string memo ){ auto sym = quantity.symbol; eosio_assert( sym.is_valid(), “invalid symbol name” ); eosio_assert( memo.size() <= 256, “memo has more than 256 bytes” ); auto sym_name = sym.name(); stats statstable( _self, sym_name ); auto existing = statstable.find( sym_name ); eosio_assert( existing != statstable.end(), “token with symbol does not exist, create token before issue” ); const auto& st = *existing; require_auth( st.issuer ); eosio_assert( quantity.is_valid(), “invalid quantity” ); eosio_assert( quantity.amount > 0, “must issue positive quantity” ); eosio_assert( quantity.symbol == st.supply.symbol, “symbol precision mismatch” ); eosio_assert( quantity.amount <= st.max_supply.amount - st.supply.amount, “quantity exceeds available supply”); statstable.modify( st, 0, [&]( auto& s ) { s.supply += quantity; }); add_balance( st.issuer, quantity, st.issuer ); if( to != st.issuer ) { SEND_INLINE_ACTION( *this, transfer, {st.issuer,N(active)}, {st.issuer, to, quantity, memo} ); }}void token::transfer( account_name from, account_name to, asset quantity, string memo ){ eosio_assert( from != to, “cannot transfer to self” ); require_auth( from ); eosio_assert( is_account( to ), “to account does not exist”); auto sym = quantity.symbol.name(); stats statstable( _self, sym ); const auto& st = statstable.get( sym ); require_recipient( from ); require_recipient( to ); eosio_assert( quantity.is_valid(), “invalid quantity” ); eosio_assert( quantity.amount > 0, “must transfer positive quantity” ); eosio_assert( quantity.symbol == st.supply.symbol, “symbol precision mismatch” ); eosio_assert( memo.size() <= 256, “memo has more than 256 bytes” ); sub_balance( from, quantity ); add_balance( to, quantity, from );}void token::sub_balance( account_name owner, asset value ) { accounts from_acnts( _self, owner ); const auto& from = from_acnts.get( value.symbol.name(), “no balance object found” ); eosio_assert( from.balance.amount >= value.amount, “overdrawn balance” ); if( from.balance.amount == value.amount ) { from_acnts.erase( from ); } else { from_acnts.modify( from, owner, [&]( auto& a ) { a.balance -= value; }); }}void token::add_balance( account_name owner, asset value, account_name ram_payer ){ accounts to_acnts( _self, owner ); auto to = to_acnts.find( value.symbol.name() ); if( to == to_acnts.end() ) { to_acnts.emplace( ram_payer, [&]( auto& a ){ a.balance = value; }); } else { to_acnts.modify( to, 0, [&]( auto& a ) { a.balance += value; }); }}} /// namespace eosioEOSIO_ABI( eosio::token, (create)(issue)(transfer) )示例命令:$cleos push action eosio.token create ‘[“usera”,“21000000.0000 DEMO”]’ -p eosio.token usera $cleos push action eosio.token issue ‘[“usera”,“21000000.0000 DEMO”,“issuance”]’ -p usera $cleos push action eosio.token tranfser ‘[“usera”,“userb”,“1000000.0000 DEMO”,“here you go”]’ -p usera 表命令:$cleos get table eosio.token DEMO stat { “rows”: [{ “supply”: “21000000.0000 DEMO” “max_supply”: “2100000000.0000 DEMO” “issuer”: “usera” } ], “more”: false } $cleos get table eosio.token usera accounts { “rows”: [{ “balance”: “20000000.0000 DEMO” } ], “more”: false } $cleos get table eosio.token userb accounts { “rows”: [{ “balance”: “10000000.0000 DEMO” } ], “more”: false } 注意:本文是在Dawn4.1代码发布时编写的。======================================================================分享一些以太坊、EOS、比特币等区块链相关的交互式在线编程实战教程:EOS教程,本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。java以太坊开发教程,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。python以太坊,主要是针对python工程师使用web3.py进行区块链以太坊开发的详解。php以太坊,主要是介绍使用php进行智能合约开发交互,进行账号创建、交易、转账、代币开发以及过滤器和交易等内容。以太坊入门教程,主要介绍智能合约与dapp应用开发,适合入门。以太坊开发进阶教程,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。C#以太坊,主要讲解如何使用C#开发基于.Net的以太坊应用,包括账户管理、状态与交易、智能合约开发与交互、过滤器和交易等。java比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Java代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Java工程师不可多得的比特币开发学习课程。php比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Php代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Php工程师不可多得的比特币开发学习课程。tendermint区块链开发详解,本课程适合希望使用tendermint进行区块链开发的工程师,课程内容即包括tendermint应用开发模型中的核心概念,例如ABCI接口、默克尔树、多版本状态库等,也包括代币发行等丰富的实操代码,是go语言工程师快速入门区块链开发的最佳选择。汇智网原创翻译,转载请标明出处。这里是原文理解eosio.token合约 ...

January 2, 2019 · 4 min · jiezi

EOS开发dApp前需要了解的五件事

EOS只有6个月(2018年12月),但从Block’tivity和State of dApps上来看,它已经是世界上最常用的区块链之一。它是第一个碳中性区块链,它发展得比以往任何时候都快。随着EOS成为2019年去中心化应用程序开发的首选,我们准备了在EOS区块链上开发dApp之前需要了解的前5个事项的简短列表。1.EOS不是以太坊人们最难理解的事情之一就是EOS不是以太坊。每个区块链都以其自己的方式是独一无二的,EOS也不例外。EOS代表Exponential Operating System,据说EOS比其他一些区块链更复杂。幸运的是,这是一件好事。对于我们开发快速,免费,可扩展和复杂的去中心化应用程序,我们需要环境和平台来完成它。我们已经看到工作dApps具有真正的市场价值,如Karma,Sense,Infiniverse。2.CPU,NET——投注和收回EOS代币关于EOS,你应该了解的关键之一是它拥有的资源以及它如何使用这些资源。在EOS Blockchain中,我们有3种类型的资源:CPU,NET和RAM。CPU:它表示操作的处理时间。如果要对区块链执行操作,则需要一些时间才能完成。此时间以微秒为单位测量CPU(s)。NET:NET或网络带宽表示EOS网络的吞吐量容量,以字节为单位进行测量。CPU和NET都是通过投注来分配。这意味着要在我们的dApp中使用它们,我们需要放弃EOS代币。看一下下图:假设我们为CPU支持2.5EOS,为NET支持2.5EOS。这相当于31200s的CPU和10000字节的NET。如果dApp的操作需要执行700s的CPU,我们实际上可以计算在将31200分成700时我们可以执行操作的次数。在上面的示例中,我们得到44。当我们执行所有44次执行,并且我们想要做更多时,有两个选项:为CPU和NET投入更多EOS代币。等待一段时间当他们空闲了然后再使用它们。这两种资源都是短暂的。你在某个时间点消耗它们,然后重新生成以供将来使用。有一个名为EOS Charge的神奇工具。基于你放置的EOS代币,它会创建一个自定义报告,说明你可以在每个dApp的EOS主网上执行的操作数。你应该知道的另一件事是,当你为CPU购买2.5EOS代币然后取消它们时,你将获得2.5EOS而不会有任何损失。使用RAM时有点不同。3.RAMRAM是EOS网络上的宝贵资源。我们在区块链上保存的所有内容都保存在RAM中。这有助于我们实现更快的速度。与使用EOS代币的CPU和NET不同,购买RAM。计算dApp需要多少RAM非常重要。这将有助于你首先将成本降至最低。你还应该知道,当数据保存在RAM中时,你可以决定谁将为其付费——用户或开发人员。4.EOS dApp 融资在开始开发之前,为你的EOS dApp寻找资金与计算CPU,NET和RAM的成本一样重要。我们创建了一篇关于Airdrop的精彩文章——区块链初创公司的新融资模式。但是,在本段中,我们将更多地讨论传统模型。仍然使用的一种模型是所谓的ICO。我们已经看到像Sense这样的项目在以太坊上进行融资,并通过shEOS将所有以太转移到EOS和EOS21协议。我个人对此时的ICO模型有点怀疑,我更喜欢最传统的一个——风险投资。Block.one创建了一个拥有10亿美元资金的风险投资,以帮助基于EOS区块链的创业公司。EOS VC在风险投资方面是独一无二的,因为它专注于投资旨在帮助进一步构建EOSIO生态系统的项目。这是Block.one在全球推动大规模采用区块链技术的使命的一部分。你有机会通过这个申请表格申请资助。5.一个dApp——多个区块链许多来自以太坊或任何类似区块链的开发商和企业家仍然不知道有关EOS网络的最令人兴奋的秘密。你可以构建一个EOS dApp,然后决定使用哪个区块链–EOS,Telos,Worbli。目前,这三个中的任何一个(将来会有更多)都会带来一些独特的东西。======================================================================分享一些以太坊、EOS、比特币等区块链相关的交互式在线编程实战教程:EOS教程,本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。java以太坊开发教程,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。python以太坊,主要是针对python工程师使用web3.py进行区块链以太坊开发的详解。php以太坊,主要是介绍使用php进行智能合约开发交互,进行账号创建、交易、转账、代币开发以及过滤器和交易等内容。以太坊入门教程,主要介绍智能合约与dapp应用开发,适合入门。以太坊开发进阶教程,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。C#以太坊,主要讲解如何使用C#开发基于.Net的以太坊应用,包括账户管理、状态与交易、智能合约开发与交互、过滤器和交易等。java比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Java代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Java工程师不可多得的比特币开发学习课程。php比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Php代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Php工程师不可多得的比特币开发学习课程。tendermint区块链开发详解,本课程适合希望使用tendermint进行区块链开发的工程师,课程内容即包括tendermint应用开发模型中的核心概念,例如ABCI接口、默克尔树、多版本状态库等,也包括代币发行等丰富的实操代码,是go语言工程师快速入门区块链开发的最佳选择。汇智网原创翻译,转载请标明出处。这里是原文EOS开发DAPP前需要了解的五件事

December 30, 2018 · 1 min · jiezi

做好 FIBOS 生态门户 —— FO 钱包 v2.0.0 新版上线

上周 FIBOS 的 FO 钱包上线最新版本,快来看看有哪些变化吧。一.视觉上的优化升以及首页快捷操作的删减和添加最初 FO 钱包上线的时候,因为要和 FIBOS 同步,有些设计细节没有打磨好,而这次的新版本中,设计师在 UI 上做了整体调整。另一方面, FO 钱包的首页和资产页都有一个很大的变化,首页隐藏了资产信息,增加了扫一扫、收款、付款、兑换四个快捷操作,同时把 DAPP 的相关功能提到了首页。在资产页面上增加了 FO 跟 CNY 之间的一个兑换比例,以后想要知道你的 FO 值多少钱,就不用再通过 EOS 去换算了。二.FO 钱包开始向应用型钱包转型随着钱包的发展,各种功能的丰富,已经有越来越多的 DAPP 入驻进来, FO 钱包开始慢慢往应用型钱包转型。未来的 FO 钱包不仅可以用来兑换 FO 或者进行 FO 的转账交易,而且可以通过 FO 实现更多的应用。大家可以用 FO 去玩一些 DAPP ,或者用 FO 进行发红包等。未来设计师会把 IM 的聊天功能嵌到 FO 中来,并且会有更多的 DAPP 入驻进来。我们希望 FO 钱包在生活中有更多的应用场景,提高大家的使用效率,让 FO 钱包真正的走向成熟。三.红包发出来之后,需要“飞一会”资产发出来之后,需要经过区块的确认,这个过程是不可逆的,是必须的,所以发出来之后要经过一点时间。如果把这个确认的时间砍掉的话,可能会存在资产分叉的风险。也就是说,可能你抢到了钱,但是最后分叉了又不属于你了。所以为了确保“你的就是你的”,这个红包确实需要飞一会儿,不过我们也在努力,以后会把这个时间尽可能缩短一些。最后,如果大家发现了红包的 bug 或者是有好的建议,欢迎向我们提出来!希望 FO 钱包能在大家的支持下越做越好!文末附上官方地址~~~https://fibos.io/https://dev.fo/搜索关注公众号「FIBOS社区」,第一时间获取技术干货!

December 29, 2018 · 1 min · jiezi

eosjs 文档(读取区块链)

读取区块链读取区块链状态只需要连接到节点的JsonRpc实例。const { JsonRpc } = require(’eosjs’);const fetch = require(’node-fetch’); // node only; not needed in browsersconst rpc = new JsonRpc(‘http://127.0.0.1:8888’, { fetch });示例获取表格行获取帐户testacc的前10个代币余额。const resp = await rpc.get_table_rows({ json: true, // Get the response as json code: ’eosio.token’, // Contract that we target scope: ’testacc’ // Account that owns the data table: ‘accounts’ // Table name limit: 10, // maximum number of rows that we want to get});console.log(resp.rows);输出:{ “rows”: [{ “balance”: “100.0000 HAK” } ], “more”: false}按索引获取一行const resp = await rpc.get_table_rows({ json: true, // Get the response as json code: ‘contract’, // Contract that we target scope: ‘contract’ // Account that owns the data table: ‘profiles’ // Table name lower_bound: ’testacc’ // Table primary key value limit: 1, // Here we limit to 1 to get only the});console.log(resp.rows);输出:{ “rows”: [{ “user”: “testacc”, “age”: 21, “surname”: “Martin” } ], “more”: false}通过二级索引获取一行const resp = await rpc.get_table_rows({ json: true, // Get the response as json code: ‘contract’, // Contract that we target scope: ‘contract’ // Account that owns the data table: ‘profiles’ // Table name table_key: ‘age’ // Table secondaray key name lower_bound: 21 // Table secondary key value limit: 1, // Here we limit to 1 to get only the});console.log(resp.rows);输出:{ “rows”: [{ “user”: “testacc”, “age”: 21, “surname”: “Martin” } ], “more”: false}获得货币余额console.log(await rpc.get_currency_balance(’eosio.token’, ’testacc’, ‘HAK’));输出:[ “1000000000.0000 HAK” ]获取帐户信息console.log(await rpc.get_account(’testacc’));输出:{ “account_name”: “testacc”, “head_block_num”: 1079, “head_block_time”: “2018-11-10T00:45:53.500”, “privileged”: false, “last_code_update”: “1970-01-01T00:00:00.000”, “created”: “2018-11-10T00:37:05.000”, “ram_quota”: -1, “net_weight”: -1, “cpu_weight”: -1, “net_limit”: { “used”: -1, “available”: -1, “max”: -1 }, “cpu_limit”: { “used”: -1, “available”: -1, “max”: -1 }, “ram_usage”: 2724, “permissions”: [ { “perm_name”: “active”, “parent”: “owner”, “required_auth”: [] }, { “perm_name”: “owner”, “parent”: “”, “required_auth”: [] } ], “total_resources”: null, “self_delegated_bandwidth”: null, “refund_request”: null, “voter_info”: null }获取区块console.log(await rpc.get_block(1));输出:{ “timestamp”: “2018-06-01T12:00:00.000”, “producer”: “”, “confirmed”: 1, “previous”: “0000000000000000000000000000000000000000000000000000000000000000”, “transaction_mroot”: “0000000000000000000000000000000000000000000000000000000000000000”, “action_mroot”: “cf057bbfb72640471fd910bcb67639c22df9f92470936cddc1ade0e2f2e7dc4f”, “schedule_version”: 0, “new_producers”: null, “header_extensions”: [], “producer_signature”: “SIG_K1_111111111111111111111111111111111111111111111111111111111111111116uk5ne”, “transactions”: [], “block_extensions”: [], “id”: “00000001bcf2f448225d099685f14da76803028926af04d2607eafcf609c265c”, “block_num”: 1, “ref_block_prefix”: 2517196066 }上一篇:交易 ...

December 28, 2018 · 2 min · jiezi

eosjs 文档(交易)

交易为了能够在区块链上发送交易和触发操作,你必须具有Api实例。签名提供程序必须包含与执行者和操作权限相对应的私钥。const { Api, JsonRpc } = require(’eosjs’);const JsSignatureProvider = require(’eosjs/dist/eosjs-jssig’); // development onlyconst fetch = require(’node-fetch’); // node only; not needed in browsersconst { TextDecoder, TextEncoder } = require(’text-encoding’); // node, IE11 and IE Edge Browsersconst privateKeys = [privateKey1];const signatureProvider = new JsSignatureProvider(privateKeys);const rpc = new JsonRpc(‘http://127.0.0.1:8888’, { fetch });const api = new Api({ rpc, signatureProvider, textDecoder: new TextDecoder(), textEncoder: new TextEncoder() });示例Buy ramconst result = await api.transact({ actions: [{ account: ’eosio’, name: ‘buyrambytes’, authorization: [{ actor: ‘useraaaaaaaa’, permission: ‘active’, }], data: { payer: ‘useraaaaaaaa’, receiver: ‘useraaaaaaaa’, bytes: 8192, }, }]}, { blocksBehind: 3, expireSeconds: 30,});Stakeconst result = await api.transact({ actions: [{ account: ’eosio’, name: ‘delegatebw’, authorization: [{ actor: ‘useraaaaaaaa’, permission: ‘active’, }], data: { from: ‘useraaaaaaaa’, receiver: ‘useraaaaaaaa’, stake_net_quantity: ‘1.0000 SYS’, stake_cpu_quantity: ‘1.0000 SYS’, transfer: false, } }]}, { blocksBehind: 3, expireSeconds: 30,});示例:Unstakeconst result = await api.transact({ actions: [{ account: ’eosio’, name: ‘undelegatebw’, authorization: [{ actor: ‘useraaaaaaaa’, permission: ‘active’, }], data: { from: ‘useraaaaaaaa’, receiver: ‘useraaaaaaaa’, unstake_net_quantity: ‘1.0000 SYS’, unstake_cpu_quantity: ‘1.0000 SYS’, transfer: false, } }]}, { blocksBehind: 3, expireSeconds: 30,});创建新帐户(多个操作)const result = await api.transact({ actions: [{ account: ’eosio’, name: ’newaccount’, authorization: [{ actor: ‘useraaaaaaaa’, permission: ‘active’, }], data: { creator: ‘useraaaaaaaa’, name: ‘mynewaccount’, owner: { threshold: 1, keys: [{ key: ‘PUB_R1_6FPFZqw5ahYrR9jD96yDbbDNTdKtNqRbze6oTDLntrsANgQKZu’, weight: 1 }], accounts: [], waits: [] }, active: { threshold: 1, keys: [{ key: ‘PUB_R1_6FPFZqw5ahYrR9jD96yDbbDNTdKtNqRbze6oTDLntrsANgQKZu’, weight: 1 }], accounts: [], waits: [] }, }, }, { account: ’eosio’, name: ‘buyrambytes’, authorization: [{ actor: ‘useraaaaaaaa’, permission: ‘active’, }], data: { payer: ‘useraaaaaaaa’, receiver: ‘mynewaccount’, bytes: 8192, }, }, { account: ’eosio’, name: ‘delegatebw’, authorization: [{ actor: ‘useraaaaaaaa’, permission: ‘active’, }], data: { from: ‘useraaaaaaaa’, receiver: ‘mynewaccount’, stake_net_quantity: ‘1.0000 SYS’, stake_cpu_quantity: ‘1.0000 SYS’, transfer: false, } }]}, { blocksBehind: 3, expireSeconds: 30,});上一篇:浏览器 ...

December 28, 2018 · 2 min · jiezi

eosjs 文档(介绍)

介绍用于使用EOSIO RPC API与基于EOSIO的区块链集成的Javascript API。安装NodeJS依赖npm install eosjs@beta or yarn add eosjs@beta浏览器发行包在本地克隆此存储库然后运行npm run build-web或yarn build-web,浏览器发行包将位于dist-web中,可以直接复制到项目存储库中。dist-web文件夹包含准备生产的缩小捆绑包以及用于调试的库的源映射版本,有关完整的浏览器用法示例,请参阅文档。导入ES模块如果你有一个转换器,则支持在浏览器中使用ES6模块语法导入,就像Babel:import { Api, JsonRpc, RpcError } from ’eosjs’;import JsSignatureProvider from ’eosjs/dist/eosjs-jssig’; // development onlyCommonJSNodeJS支持使用commonJS语法导入。const { Api, JsonRpc, RpcError } = require(’eosjs’);const JsSignatureProvider = require(’eosjs/dist/eosjs-jssig’); // development onlyconst fetch = require(’node-fetch’); // node only; not needed in browsersconst { TextEncoder, TextDecoder } = require(‘util’); // node only; native TextEncoder/Decoder const { TextEncoder, TextDecoder } = require(’text-encoding’); // React Native, IE11, and Edge Browsers only基础用法签名提供者签名提供者持有私钥并负责签名交易。在浏览器中使用JsSignatureProvider并不安全,只能用于开发目的,在网页上下文之外使用安全保管库,以确保在生产中签名交易时的安全性。const defaultPrivateKey = “5JtUScZK2XEp3g9gh7F8bwtPTRAkASmNrrftmx4AxDKD5K4zDnr”; // useraaaaaaaaconst signatureProvider = new JsSignatureProvider([defaultPrivateKey]);JSON-RPC打开与JSON-RPC的连接,包括在NodeJS上的fetch。const rpc = new JsonRpc(‘http://127.0.0.1:8888’, { fetch });API在浏览器中使用时包含textDecoder和textEncoder。const api = new Api({ rpc, signatureProvider, textDecoder: new TextDecoder(), textEncoder: new TextEncoder() });发送交易transact()用于使用可选的配置对象参数将交易签名并推送到区块链,此参数可以重写broadcast: true的默认值,并可用于填充给定blocksBehind和expireSeconds的TAPOS字段。如果没有配置选项,则预计将使用TAPOS字段(expiration、ref_block_num、ref_block_prefix)解压缩交易,并自动将其广播到链上。(async () => { const result = await api.transact({ actions: [{ account: ’eosio.token’, name: ’transfer’, authorization: [{ actor: ‘useraaaaaaaa’, permission: ‘active’, }], data: { from: ‘useraaaaaaaa’, to: ‘useraaaaaaab’, quantity: ‘0.0001 SYS’, memo: ‘’, }, }] }, { blocksBehind: 3, expireSeconds: 30, }); console.dir(result);})();错误处理使用RpcError处理RPC错误。…try { const result = await api.transact({ …} catch (e) { console.log(’\nCaught exception: ’ + e); if (e instanceof RpcError) console.log(JSON.stringify(e.json, null, 2));}…运行测试自动单元测试套件npm run test or yarn testWeb集成测试套件运行npm run build-web构建浏览器发行包,然后在你选择的浏览器中打开src/tests/web.html,该文件应该运行6次测试,在每次测试后将结果传递到网页上,延迟时间为2秒,最后两个测试应该为无效的交易和无效的rpc调用将异常传递到网页上。上一篇:eosjs 文档(目录)下一篇:浏览器 ...

December 28, 2018 · 1 min · jiezi

eosjs 文档(目录)

eosjs 文档用于使用EOSIO RPC API与基于EOSIO的区块链集成的Javascript API。重要!最近发布了针对eosjs的重大改写,一定要锁定你的依赖项。如果你正在寻找以前版本的eosjs,可以在这里找到它。指南介绍浏览器交易读取区块链参考APIAPI接口JS-SigJSON-RPC数字RPC-ErrorRPC接口序列化SerialBufferSerializerStateActionAuthorizationContractCreateTypeArgsFieldSerializedActionSerializerOptionsSymbolType

December 28, 2018 · 1 min · jiezi

eosjs 文档(浏览器)

浏览器用法npm run build-web或yarn build-web。为所有交易重用api对象,它缓存ABI以减少网络使用,只调用一次new eosjs_api.default(…)。<pre style=“width: 100%; height: 100%; margin:0px; “></pre><script src=‘dist-web/eosjs-api.js’></script><script src=‘dist-web/eosjs-jsonrpc.js’></script><script src=‘dist-web/eosjs-jssig.js’></script><script> let pre = document.getElementsByTagName(‘pre’)[0]; const defaultPrivateKey = “5JtUScZK2XEp3g9gh7F8bwtPTRAkASmNrrftmx4AxDKD5K4zDnr”; // useraaaaaaaa const rpc = new eosjs_jsonrpc.default(‘http://127.0.0.1:8888’); const signatureProvider = new eosjs_jssig.default([defaultPrivateKey]); const api = new eosjs_api.default({ rpc, signatureProvider }); (async () => { try { const result = await api.transact({ actions: [{ account: ’eosio.token’, name: ’transfer’, authorization: [{ actor: ‘useraaaaaaaa’, permission: ‘active’, }], data: { from: ‘useraaaaaaaa’, to: ‘useraaaaaaab’, quantity: ‘0.0001 SYS’, memo: ‘’, }, }] }, { blocksBehind: 3, expireSeconds: 30, }); pre.textContent += ‘\n\nTransaction pushed!\n\n’ + JSON.stringify(result, null, 2); } catch (e) { pre.textContent = ‘\nCaught exception: ’ + e; if (e instanceof eosjs_jsonrpc.RpcError) pre.textContent += ‘\n\n’ + JSON.stringify(e.json, null, 2); } })();</script>调试如果你想要可读的源文件进行调试,请将文件引用更改为dist-web/debug目录下的-debug.js文件,这些文件只用于开发,因为它们的大小是缩小了10倍多的版本,导入调试版本将增加最终用户的加载时间。IE11和Edge支持如果你需要支持IE11或Edge,你还需要安装文本编码的polyfill,因为eosjs签名依赖于IE11和Edge不提供的TextEncoder。将TextEncoder和TextDecoder传递给API构造函数,请参阅https://github.com/inexorabletash/text-encoding中的文档,以确定将其包含在项目中的最佳方法。上一篇:介绍 ...

December 28, 2018 · 1 min · jiezi

什么是区块链预言机(BlockChain Oracle)

预言机 Oracle 是区块链中非常重要的一个功能,但我发现很少有人讨论,也可能很多人对此并不了解。而网上关于预言机的文章很少,很多也没有讲明白,甚至有些还是错误的。所以我整理了一篇详细的文章,分享给大家,相信看完一定会对 Oracle 有一个深层次的了解。1、预言机(Oracle)是什么?11 月 6 日,在中国人民银行发布的《区块链能做什么?不能做什么?》的报告中,是这样对预言机定义的。区块链外信息写入区块链内的机制,一般被称为预言机 (oracle mechanism) 。预言机的功能就是将外界信息写入到区块链内,完成区块链与现实世界的数据互通。它允许确定的智能合约对不确定的外部世界作出反应,是智能合约与外部进行数据交互的唯一途径,也是区块链与现实世界进行数据交互的接口。听上去很难理解,我们举例来说。大家会很形象的把公链比作操作系统(Windows、IOS、安卓),DAPP 类比的话就是 APP,那么预言机可以形象的比做 API 接口。API 是一组定义、程序及协议的集合,通过 API 接口实现计算机软件之间的相互通信。这样类比虽然不准确,但意思就是预言机是区块链和现实世界之间的纽带,可以实现数据互通的工具。2、Oracle 为什么被中译为预言机?跟别人提起预言机,很多人的第一反应都是预测市场,预言机这个名字确实容易想到预测。Oracle 最初是来源于古希腊宗教,意为“神谕、先知、预言”。而在互联网领域,预言机(英语:oracle machine),又称谕示机,是一种抽象电脑,用来研究决定型问题。可以被视为一个多了个黑盒子(预言者)的图灵机,这个黑盒子的功能是可以在单一运算之内解答特定问题。也许你会好奇这跟甲骨文公司有什么关系吗?其实没有关系。Oracle 在中国叫甲骨文公司的原因可能是另一个故事。在中国商朝晚期,王室把在动物骨骼或龟甲上做占卜记事的文字叫甲骨文,甲骨文被英译为 Oracle bone script,后来 Oracle 公司到中国中译为了甲骨文公司。(很有道理的猜测 哈哈哈)3、区块链为什么需要预言机?区块链是一个确定性的、封闭的系统环境,目前区块链只能获取到链内的数据,而不能获取到链外真实世界的数据,区块链与现实世界是割裂的。一般智能合约的执行需要触发条件,当智能合约的触发条件是外部信息时(链外),就必须需要预言机来提供数据服务,通过预言机将现实世界的数据输入到区块链上,因为智能合约不支持对外请求。具体原因是这样的。区块链是确定性的环境,它不允许不确定的事情或因素,智能合约不管何时何地运行都必须是一致的结果,所以虚拟机(VM)不能让智能合约有 network call(网络调用),不然结果就是不确定的。也就是说智能合约不能进行 I/O(Input/Output,即输入/输出),所以它是无法主动获取外部数据的,只能通过预言机将数据给到智能合约。我们通过一个例子来说明一下。假设现在我被关进了一个小黑屋里(不要多想,只是例子????),我对外面的世界发生了什么一无所知,不知道外面是否有人,即使呼叫也没有人回应,而我知道外界信息的方式,只有外面的人在门口把他看到的听到的都告诉我,我才可以得知。例子虽然不太恰当,但智能合约就像这个例子中的我一样,它无论何时何地,都无法主动向外寻求信息,只能外部把消息或数据给到里面。而预言机就是这个在外面输送消息和数据的人。好像这么看来,智能合约并不是很智能呀,是的,智能合约其实是完成的不智能的事情,即写好了条件和结果,当给它条件的时候,就可以触发,但也不会马上执行,还需要合约相关的人进行私钥签署才可以执行。所以,网上很多文章其实都有水分,比如智能合约某个时间或者触发某个条件就可以自动执行之类的,只能说这样的句子在逻辑上可能是有问题的。关于预言机的很多文章也有水分,描述的并不准确。好了,上面就是区块链为什么需要预言机,因为智能合约无法主动去获取链外的数据,只能被动接受数据。4、预言机怎么解决这个问题?这是理想中预言机的工作流程,即用户的智能合约把请求给链上 Oracle 合约,通过链下的 API 接口获得外部数据,更确切的说是外部把数据给链上的 Oracle 合约,然后 Oracle 合约再把数据给用户的智能合约。或许很难理解,因为在互联网中,调用数据是非常容易的,只需要在程序中写调用的代码就可以了。但是区块链与外部世界的数据交互,确实不能进行这样的操作。5、预言机的应用场景有哪些?预言机作为区块链与现实世界进行数据交互的桥梁,应用场景非常多,可以说一切需要与链下进行数据交互的DApp都需要预言机。比如金融衍生品交易平台、借贷平台、快递追踪/IoT、稳定币、博彩游戏、保险、预测市场等等。我们还是举例来说。先说最近币圈比较火热的博彩游戏为什么需要预言机。博彩游戏的核心是不可预测、可验证的随机数,从而决定赌注的最终结果,但是在链上是无法生成随机数的或者说在链上的随机数是可以被预测和破解的,这时候就需要预言机从外部给智能合约安全的、不可预测的随机数。现在的大多数博彩游戏都是在链上生成随机数,很容易被预测和破解,导致资产被盗,大家有兴趣的可以去看一下 DApp 被盗的相关研究报告,很多因为随机数问题被盗的。比如 BetDice、Dice2.Win。如果大家很感兴趣,可以看一下我男神 DOS Network 创始人 jonny 关于《智能合约中的随机数》的分享。PPT链接:https://zhuanlan.zhihu.com/p/…其实,早在 Fomo3D 这个游戏出来之后,以太坊的 Team Leader 就在推特上说过链上是无法生成随机数的。Dear devs… you can`t generate random numbers on chain!我们再来看一个关于快递追踪的例子。假设当我通过某个 DApp 购物平台购买某件物品快递过来的时候,真实世界中的快递寄送或到达信息,就可以通过 Oracle 把数据传递到链上,然后触发链上的智能合约,我用自己的私钥确认收到了快递,并完成付款。大家发现了吗?这里的智能合约不能自动执行,而是需要我用自己的私钥进行确认,智能合约保证的是没有第三方机构做担保和资金周转(比如支付宝),这就是智能合约的价值。其他的案例就不细说了,比如稳定币需要链下的利率,保险需要链下的病例或车况等,具体可以看这篇文章《Oracle—区块链与现实世界的纽带》。6、目前预言机项目和解决方案有哪些?目前在预言机领域探索的项目还不是很多,每一个项目的预言机解决方案都略有差异,我找了几家不同解决方案的预言机项目。Oraclize:为以太坊提供中心化预言机服务Oraclize 依托亚马逊 AWS 服务和 TLSNotary 技术,是一个可证明的诚实的预言机服务,不过它是中心化的,目前只能在以太坊网络使用,而且 gas 费较高。但是不妨碍它是目前比较受欢迎的预言机服务,可能也是因为没有其他更好的选择吧。ChainLink:以太坊上第一个去中心化预言机解决方案ChainLink 的解决方案是通过在链上的智能合约和链下的数据节点,通过奖惩机制和聚合模型的方式,进行数据的请求和馈送。不过也有一些不足,比如链式聚合成本较高,拓展性差,基于声誉系统容易集中化。欧链 OracleChain:EOS 上的第一个去中心化预言机解决方案欧链很早就提出了预言机的想法和方案,采用自主的 PoRD 机制(Proof-of-Reputation&Deposit),本质上是一种抵押代币奖惩机制的声誉系统,奖励数据节点惩罚作恶节点,可以实现 Augur、Gnosis 等预测市场应用的功能,还能支撑对链外数据有更高频率访问需求的智能合约业务。预测市场的结果本身有时也可以作为 oracle 的输入数据源。欧链更像是预测市场,而且单纯的声誉系统容易集中化。DOS Network:支持多条主流公链的去中心化预言机服务网络DOS Network 是一个 Layer-2 的预言机解决方案,它通过在链上部署一个轻量级智能合约,链下是一个 p2p 网络,服务节点的选取和数据验证采用 VRF+阈值签名等技术,保证了去中心化和数据安全,并达到快速反应。可以适配所有主流公链,比如以太坊、EOS、波场、Thunder。目前已在以太坊测试网发布 alpha 版本 https://dosnetwork.github.io/docs。另外有一个单节点的 demo 视频 https://www.youtube.com/watch?v=yf2fjYSVXNk&t=100s看完文章是不是对区块链预言机有了更深的了解呢,区块链作为一种新兴的技术,还需要不断的探索和尝试。而预言机在其中扮演着非常重要的角色,让我们共同期待预言机技术的不断成熟,进而促进更多区块链与现实世界进行数据交互的 DApp 落地。 ...

December 28, 2018 · 1 min · jiezi

EOSIO 指南(链API)

链APIget_info返回包含区块链的各种详细信息的对象。http://127.0.0.1:8888/v1/chain/get_infoNodevar request = require(“request”);var options = { method: ‘POST’, url: ‘http://127.0.0.1:8888/v1/chain/get_info’ };request(options, function (error, response, body) { if (error) throw new Error(error); console.log(body);});响应{ “server_version”: “d9ad8eec”, “head_block_num”: 8592, “last_irreversible_block_num”: 8591, “head_block_id”: “00002190e805475db152be7d3f4f1a075efaed42827cd551b0e23c7feabbedac”, “head_block_time”: “2018-04-27T17:40:34”, “head_block_producer”: “eosio”}get_block返回包含有关区块链上特定块的各种详细信息的对象。http://127.0.0.1:8888/v1/chain/get_blockNodevar request = require(“request”);var options = { method: ‘POST’, url: ‘http://127.0.0.1:8888/v1/chain/get_block’ };request(options, function (error, response, body) { if (error) throw new Error(error); console.log(body);});body参数参数名参数类型描述必要示例block_num_or_idstring提供块编号或块ID是5响应{ “previous”: “00000004471d48fe40706e73ce27f9cf7bac1704ae55279c7a58c0173718a711”, “timestamp”: “2018-04-18T16:24:23.500”, “transaction_mroot”: “e366c0cc3519bb0f2ddaec20928fa4d6aae546194bb1c4205c67be429147ed4a”, “action_mroot”: “77e5e91b594ab4ebc44ebc8c7ecdc9d26409c5a07452d3b20a4840562fdeb658”, “block_mroot”: “4ef85b0d212f3fffabdd65680d32dd7dded3461d9df226a6e3dc232e42978f8b”, “producer”: “eosio”, “schedule_version”: 0, “new_producers”: null, “producer_signature”: “EOSJzEdFDsueKCerL7a6AdxMxiT851cEiugFB7ux1PAGn5eMmco8j32NsaKupxibheQGVFEqyEdjMub67VZjKmsLzuNxxKtUA”, “regions”: [{ “region”: 0, “cycles_summary”: [ [{ “read_locks”: [], “write_locks”: [], “transactions”: [{ “status”: “executed”, “kcpu_usage”: 2, “net_usage_words”: 38, “id”: “9880c128683e24845ccd282ebe026bd522f7fa9c6278d885f6ed35164c680669” }] }] ] }], “input_transactions”: [], “id”: “000000056d75b0581b4fbb96affa36669a37173d21f46f8cb974f760e94bbe14”, “block_num”: 5, “ref_block_prefix”: 2528857883}get_block_header_statehttp://127.0.0.1:8888/v1/chain/get_block_header_stateNodevar request = require(“request”);var options = { method: ‘POST’, url: ‘http://127.0.0.1:8888/v1/chain/get_block_header_state’ };request(options, function (error, response, body) { if (error) throw new Error(error); console.log(body);});body参数参数名参数类型描述必要示例block_num_or_idstring提供块编号或块ID否1get_account返回一个对象,其中包含有关区块链上特定帐户的各种详细信息。http://127.0.0.1:8888/v1/chain/get_accountNodevar request = require(“request”);var options = { method: ‘POST’, url: ‘http://127.0.0.1:8888/v1/chain/get_account’ };request(options, function (error, response, body) { if (error) throw new Error(error); console.log(body);});body参数参数名参数类型描述必要示例account_namestring提供帐户名称是eosio响应{ “account_name”: “eosio”, “permissions”: [{ “perm_name”: “active”, “parent”: “owner”, “required_auth”: { “threshold”: 1, “keys”: [{ “key”: “EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV”, “weight”: 1 }], “accounts”: [] } }, { “perm_name”: “owner”, “parent”: “”, “required_auth”: { “threshold”: 1, “keys”: [{ “key”: “EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV”, “weight”: 1 }], “accounts”: [] } }]}get_abihttp://127.0.0.1:8888/v1/chain/get_abiNodevar request = require(“request”);var options = { method: ‘POST’, url: ‘http://127.0.0.1:8888/v1/chain/get_abi’ };request(options, function (error, response, body) { if (error) throw new Error(error); console.log(body);});body参数参数名参数类型描述必要示例account_namestring要检索ABI的帐户名称否eosio.tokenget_code返回一个对象,其中包含有关区块链上特定智能合约的各种详细信息。http://127.0.0.1:8888/v1/chain/get_codeNodevar request = require(“request”);var options = { method: ‘POST’, url: ‘http://127.0.0.1:8888/v1/chain/get_code’ };request(options, function (error, response, body) { if (error) throw new Error(error); console.log(body);});body参数参数名参数类型描述必要示例account_namestring提供智能合约帐户名称是currency响应{ “name”:“currency”, “code_hash”:“a1c8c84b4700c09c8edb83522237439e33cf011a4d7ace51075998bd002e04c9”, “wast”:"(module\n (type $0 (func (param i64 i64 i32) (result i32)))\n …truncated", “abi”: { “types”: [{ “new_type_name”: “account_name”, “type”: “name” } ], “structs”: [{ “name”: “transfer”, “base”: “”, “fields”: [ {“name”:“from”, “type”:“account_name”}, {“name”:“to”, “type”:“account_name”}, {“name”:“quantity”, “type”:“uint64”} ] },{ “name”: “account”, “base”: “”, “fields”: [ {“name”:“key”, “type”:“name”}, {“name”:“balance”, “type”:“uint64”} ] } ], “actions”: [{ “name”: “transfer”, “type”: “transfer” } ], “tables”: [{ “name”: “account”, “type”: “account”, “index_type”: “i64”, “key_names” : [“key”], “key_types” : [“name”] } ]}code_as_wasm自1.2.2起已弃用。get_raw_code_and_abihttp://127.0.0.1:8888/v1/chain/get_raw_code_and_abiNodevar request = require(“request”);var options = { method: ‘POST’, url: ‘http://127.0.0.1:8888/v1/chain/get_raw_code_and_abi’ };request(options, function (error, response, body) { if (error) throw new Error(error); console.log(body);});body参数参数名参数类型描述必要示例account_namestring帐户名称以获取代码和abi否eosioget_table_rows返回包含指定表中行的对象。http://127.0.0.1:8888/v1/chain/get_table_rowsNodevar request = require(“request”);var options = { method: ‘POST’, url: ‘http://127.0.0.1:8888/v1/chain/get_table_rows’ };request(options, function (error, response, body) { if (error) throw new Error(error); console.log(body);});body参数参数名参数类型描述必要示例scopestring数据范围所在的帐户名称是initacodestring控制提供的表的智能合约的名称是currencytablestirng要查询的表的名称是accounttable_keystring 否initajsonboolean返回json对象或返回格式化的响应是truelower_boundstring过滤结果以返回不小于集合中提供的值的第一个元素否 upper_boundstring过滤结果以返回大于集合中提供的值的第一个元素否 limitint32限制响应中返回的结果否10index_positionstring使用的索引的位置,例如,1表示主索引,2表示次要索引,等等否1key_typestringindex_position指定的键的类型(例如:uint64_t或name)否 encode_typestring 否dec响应{ “rows”: [ { “account”: “account”, “balance”: 1000 } ], “more”: false}get_table_by_scopehttp://127.0.0.1:8888/v1/chain/get_table_by_scopeNodevar request = require(“request”);var options = { method: ‘POST’, url: ‘http://127.0.0.1:8888/v1/chain/get_table_by_scope’ };request(options, function (error, response, body) { if (error) throw new Error(error); console.log(body);});body参数参数名参数类型描述必要示例codestring返回表数据的合同的name是 tablestring按表过滤结果否0lower_boundstring过滤结果以返回不小于集合中提供的值的第一个元素否 upper_boundstring过滤结果以返回大于集合中提供的值的第一个元素否 limitint32限制响应中返回的结果否10get_currency_balancehttp://127.0.0.1:8888/v1/chain/get_currency_balanceNodevar request = require(“request”);var options = { method: ‘POST’, url: ‘http://127.0.0.1:8888/v1/chain/get_currency_balance’ };request(options, function (error, response, body) { if (error) throw new Error(error); console.log(body);});查询参数参数名参数类型描述必要示例codestring 否 accountstring获取余额的账户否 symbolstring要查询的符号否 abi_json_to_bin将json序列化为二进制十六进制,生成的二进制十六进制通常用于push_transaction中的数据字段。http://127.0.0.1:8888/v1/chain/abi_json_to_binNodevar request = require(“request”);var options = { method: ‘POST’, url: ‘http://127.0.0.1:8888/v1/chain/abi_json_to_bin’ };request(options, function (error, response, body) { if (error) throw new Error(error); console.log(body);});body参数参数名参数类型描述必要示例codestring提供帐户名称否currencyactionstring提供操作参数否transferargsjson提供json参数否{“from”:“eosio”,“to”:“eosio”,“quantity”:1000}响应{ “binargs”: “000000008093dd74000000000094dd74e803000000000000”, “required_scope”: [], “required_auth”: []}abi_bin_to_json将二进制十六进制序列化为json。http://127.0.0.1:8888/v1/chain/abi_bin_to_jsonNodevar request = require(“request”);var options = { method: ‘POST’, url: ‘http://127.0.0.1:8888/v1/chain/abi_bin_to_json’ };request(options, function (error, response, body) { if (error) throw new Error(error); console.log(body);});body参数参数名参数类型描述必要示例codestring提供帐户名称是currencyactionstring提供操作名称是transferbinargsstring提供二进制参数是 响应{ “args”: { “from”: “initb”, “to”: “initc”, “quantity”: 1000 }, “required_scope”: [], “required_auth”: []}get_required_keys返回签名交易所需的密钥。http://127.0.0.1:8888/v1/chain/get_required_keysNodevar request = require(“request”);var options = { method: ‘POST’, url: ‘http://127.0.0.1:8888/v1/chain/get_required_keys’ };request(options, function (error, response, body) { if (error) throw new Error(error); console.log(body);});body参数参数名参数类型描述必要示例transactionjson提供交易对象是 available_keys字符串数组提供可用的密钥是 响应{ “required_keys”: [ “EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV” ]}示例transaction{ “ref_block_num”: “100”, “ref_block_prefix”: “137469861”, “expiration”: “2017-09-25T06:28:49”, “scope”: [“initb”, “initc”], “actions”: [{ “code”: “currency”, “type”: “transfer”, “recipients”: [“initb”, “initc”], “authorization”: [{ “account”: “initb”, “permission”: “active” }], “data”: “000000000041934b000000008041934be803000000000000” }], “signatures”: [], “authorizations”: []}available_keys[“EOS4toFS3YXEQCkuuw1aqDLrtHim86Gz9u3hBdcBw5KNPZcursVHq”, “EOS7d9A3uLe6As66jzN8j44TXJUqJSK3bFjjEEqR4oTvNAB3iM9SA”, “EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV”]get_currency_statshttp://127.0.0.1:8888/v1/chain/get_currency_statsNodevar request = require(“request”);var options = { method: ‘POST’, url: ‘http://127.0.0.1:8888/v1/chain/get_currency_stats’ };request(options, function (error, response, body) { if (error) throw new Error(error); console.log(body);});body参数参数名参数类型描述必要示例codestring 否 symbolstring获取统计数据的货币符号否SYSget_producershttp://127.0.0.1:8888/v1/chain/get_producersNodevar request = require(“request”);var options = { method: ‘POST’, url: ‘http://127.0.0.1:8888/v1/chain/get_producers’ };request(options, function (error, response, body) { if (error) throw new Error(error); console.log(body);});body参数参数名参数类型描述必要示例limitstring要检索的生产者总数否 lower_boundstring 否 jsonboolean以JSON格式返回结果?否truepush_blockhttp://127.0.0.1:8888/v1/chain/push_blockNodevar request = require(“request”);var options = { method: ‘POST’, url: ‘http://127.0.0.1:8888/v1/chain/push_block’ };request(options, function (error, response, body) { if (error) throw new Error(error); console.log(body);});body参数参数名参数类型描述必要示例timestampdate-time 否 producerstring 否 confirmedint32 否0previousstring 否 transaction_mrootstring 否 action_mrootint32 否0versionstring 否 new_producers字符串数组 否 header_extensions字符串数组 否 producer_signaturestring 否 transactionsarray 否 block_extensions字符串数组 否 push_transaction此方法需要JSON格式的交易,并尝试将其应用于区块链。http://127.0.0.1:8888/v1/chain/push_transactionNodevar request = require(“request”);var options = { method: ‘POST’, url: ‘http://127.0.0.1:8888/v1/chain/push_transaction’ };request(options, function (error, response, body) { if (error) throw new Error(error); console.log(body);});body参数参数名参数类型描述必要示例signatures字符串数组授权交易所需的签名数组否 compressionstring使用压缩,通常是false否falsepacked_context_free_datastringjson到十六进制否 packed_trxstringjson十六进制否 响应{ ’transaction_id’ = “1…"}push_transactions此方法需要JSON格式的交易,并尝试将其应用于区块链,此方法一次推送多个交易。http://127.0.0.1:8888/v1/chain/push_transactionsNodevar request = require(“request”);var options = { method: ‘POST’, url: ‘http://127.0.0.1:8888/v1/chain/push_transactions’ };request(options, function (error, response, body) { if (error) throw new Error(error); console.log(body);});body参数参数名参数类型描述必要示例bodyjson提供交易的授权否 响应{ ’transaction_id’ = “1…"}这里的ref_block_num和ref_block_prefix是last_irreversible_block的/v1/chain/get_block的结果,可以通过调用/v1/chain/get_info找到last_irreversible_block,你还需要使用/v1/wallet/sign_transaction来获取正确的签名。 ...

December 25, 2018 · 4 min · jiezi

EOSIO 指南(浏览源码)

浏览源码Github所有源代码都可以在GitHub上找到。如果你想要比github更高效的浏览源代码,见下文。SourceGraph链接EOSIOEOS JSEOS JS Keygen。编码标准这是EOSIO软件的软件编码标准。类型标准化方法结构小写单词之间使用_,包含常量类小写单词之间使用_,包含常量方法小写单词之间使用_,包含常量类型小写单词之间使用_,包含常量模板参数驼峰式大小写,没有空格宏大写注释块:/Comment Block/内联注释/** Comments **/。缩进不要使用制表符,使用3个空格。

December 25, 2018 · 1 min · jiezi

FIBOS 发布了服务于区块链项目落地的稳定币——FOD

2018年12月21日,FIBOS 发布了稳定币——FDO,并且成功通过了社区多签。在 FIBOS 生态中有不少项目在实体经济落地时需要保障项目价值的稳健发展,所以需要以稳定币作为通证准备金。为满足生态的发展需求,FDO应运而生,有兴趣的朋友可以在 FIBOS 论坛了解详细信息:http://forum.fo/index.php?app… 目前,区块链的发展仍然处在初期,其数字资产价格波动性大,严重阻碍了自身成为价值交换的媒介,很难履行价值尺度的功能,于是稳定币出现了。稳定币的出现能大幅减少区块链资产和以法币为基础的金融资产间的隔阂,为区块链资产打开众多新的应用场景。也有业内人士把稳定币看做行业最重要的基础设施,就像移动支付对于互联网行业的重要性一样。 当然,所谓“稳定”币,也是一个相对的概念。就像美元最初也是依靠着美国的综合实力与黄金储备,逐渐成为全球认可度最高的通行“稳定”货币。当前,在加密数字货币市场中,稳定币的主要作用是满足投资者的避险需求。 随着区块链项目不断与实体经济相结合,对项目通证价值的稳定性提出了要求,因为一个价格剧烈波动的通证是无法真正服务于实体项目的发展。 FIBOS 默认提供了以 IBO 为基础经济模型的发币方式。IBO(Initial Bancor Offering) 模式以锚定区块链资产发行通证的方式,大大提高了项目通证的内在价值,有利于服务实体项目健康、稳步地发展。然而,作为Bancor准备金的区块链资产价格受市场影响波动大,又不利于实体项目的落地和发展。因此,需要一种价值相对稳定,价格变化幅度小的的区块链资产作为准备金,这也就是常说的“稳定币”。 经过综合考量,目前 FIBOS 选择USDC作为稳定币来源,通过去中心化的跨链技术生成稳定币 FOD,USDC与FOD是1:1锚定。具体而言,FOD主要用途如下:1.以FOD作为项目准备金,发行项目的智能通证。2.基于Bancor模型发行项目稳定币,与FOD是1:1锚定。3.以项目稳定币为准备金,发行项目的智能通证。 目前,基于FIBOS平台有多个项目正在规划基于稳定币发行项目通证。比如,全球最大的游戏虚拟资产交易平台,比价器项目;进口美国高端Jeep整车改装项目;拥有一万多会员的酒吧众筹项目等等。相信 FDO 的出现会让更多的项目成功落地到实体经济,促进整个生态系统的良性发展。文末附上官方地址~~~https://fibos.io/https://dev.fo/搜索关注公众号「FIBOS社区」,第一时间获取技术干货!

December 24, 2018 · 1 min · jiezi

区块链2018年度盘点

加密数字货币价格巅峰,区块链成二线企业股价春药2018 年 1 月 8 日,是区块链行业的高光时刻,整个加密数字货币市值 8139 亿美元,人民币近 6 万亿元。在 10 天之前,12 月 18 日,比特币作为知名度最高的数字币,到达其诞生以来的最高点,各交易所均价逼近 2 万美元。看着比特币的涨势图,距离看好者所说的 10 万美元似乎触手可及,比特币成为区块链和一夜暴富的代名词。各大媒体渠道上,炒币一夜暴富的故事比比皆是,区块链概念被扭曲着想走向普罗大众。1 月 5 日,中概股一家名不见经传的公司中网载线暴涨近 700%,甩开猎豹移动、迅雷、聚美优品等大涨的中概股。直接原因是,当日,中网载线刚刚宣布与井通网络科技有限公司合作开展区块链产业。区块链概念的春药作用在新年前两天就有所应验,人人网宣布涉足区块链、发行虚拟货币 RR Coin,股价暴涨近 80%。区块链数字货币在股票市场是真的还是比较有前景的,在金融领域有比较深的影响。疯狂 ICO 非法融资倒逼监管出手据 ICOdata 统计,2017 年 12 月和 2018 年 1 月,ICO 项目融资总额分别为 16.62 亿美元和 15.22 亿美元,2 个月 ICO 总计融资近 32 亿美元。相比较之下,2004 年创办的搜狗市值也才近 25 亿美元。ICO 泡沫的疯狂程度由此可窥。从 2017 年年末到达的 ICO 高潮在 1 月仍在继续,各个社群中活跃的糖果散发者和代投是火热的拉新者,每个人都在用 Telegram。3 个月前的 ICO 94 禁令早已被财富故事冲击得荡然无存,OTC 场外交易平台中,银行卡、支付宝、微信等最便捷的支付方式,成为新韭菜进入和币圈扩张得最大便利条件。1 月 19 日,监管终于出手,央行结算司下发《关于开展为非法虚拟货币交易提供支付服务自查整改工作的通知》特急文件,要求严禁各支付机构为虚拟货币交易提供服务。虚拟货币交易的入场通道将被勒令关闭,随即,支付宝限制交易收款方,银行开始排查交易账号提示风险。对于非法融资假冒的投资方式大家要提高自己的谨慎啊,投资者一方面要提高辨别能力,多对企业的投资资质揭秘“3点钟无眠区块链群”,曾7天发红包过百万6月3日开始,一个「3点钟&XMX全球社群联盟」的概念横空出世,并声称「21天内拉满2100个社群,105万人的规模。」首日由99个大V带头,在12小时内完成建立99个500人的群。游戏领域营销出生的玉红,对于这种「社群新玩法」,可谓是驾轻就熟。众多大佬当天就纷纷宣布加入这场「伟大的实验」,更有大佬在自己朋友圈公开评价:「不得不佩服玉红的传销能力。」虽然三点钟区块链的营销模式很棒,拉了很多人,但是之后的价格暴跌,使投资者血本无归,也同样受到了相应的嘲讽。同时响马叔评价说,三点钟的XMAX代码就是改的面目全非的EOS代码,也是一场收割韭菜的狂野游戏。BEC被黑一夜归零,美图出局4月22日下午13时左右,才发行两个月左右的BEC美蜜合约出现重大漏洞,黑客通过合约的批量转账方法无限生成代币,天量BEC从两个地址转出,引发抛售潮。当日,BEC的价值几乎归零。3日后,美图发声明宣布终止与BEC美链合作,同时美图重申没有、也不会发行任何数字货币。虽然BEC被盗事件以代币归零告终,但智能合约漏洞导致的安全问题却刚刚开始。黑客们好像从BEC被盗事件中看到了赚钱的契机,都开始盯上了ERC20代币的智能合约,意图通过发祥漏洞大赚一笔。同时,区块链安全公司也开始崭露头角。随着一系列以太坊漏洞被安全公司曝出,以太坊的安全受到前所未有的质疑。数字货币依然有漏洞,对于安全方面应该加强重视。同时,区块链安全公司也开始崭露头角。随着一系列以太坊漏洞被安全公司曝出,以太坊的安全受到前所未有的质疑。交易所模式创新,韭菜项目方双收割3 月初,让整个币圈沸腾的是火币 HADAX 投票上币。交易所上币新模式,号称为打破交易所的天价上币费机制,让上币权回到用户手中。实际上是打着自主上币的幌子,最终演变成项目方刷钱上币,谁出得多,谁上交易所。类比股市,A 股上市费用 3800 万人民币,港股上市费用 3000 万港币,火币上币费用 8000 个 ETH(按照均价 6000 元计算,上币总价 4800 万元),加密数字货币的新模式直白又露骨:谁钱多谁上市。交易所的企图远不止此,投票上币的通用币种是火币的平台币 HT,项目方上币的过程不断为 HT 提高流动量,拉高价格。这一模式被业内诟病圈钱太过露骨,火币紧急调整上币规则,但从后来的上币结果来看,并没有改变什么。所以区块链规则和制度要更加完善,现有的漏洞会让投机取巧者获得不正当的利益,后期应当健全完善这些系统,形成一个良性的环境半中心化的 EOS 生态起步EOS 生态中,BM 跑路和社区建设产生的化学反应,使得 EOS 起步和创始人 BM(真名 Dan Larimer)离职的消息相互交织着,也相互成就着。这也不难理解,时至今日,EOS 上 DAPP 数十个,社区仍有人每天按时发问:「BM 跑路了吗?」3 月 4 日晚间「海外币圈」自媒体发布《EOS 被曝项目创世大神即将离职,项目开发将如何进行?》,放任该消息发酵一晚,次日早间,BM 在 Telegram 群内否认离开一说。和 BM 跑路一样备受关注的是 EOS 超级节点投票。赢得主节点将获得 EOS 每年增发 5% 收益中的大部分,每年每个节点大约能得到 238 万个 EOS,按照当时价格(EOS/RMB ¥44.2),一个节点每年可以分到 1 亿元的奖励。这吸引庄家级玩家入场竞选。通过公开兜售未来奖励,EOS 成为年度盛会,知名度骤然提高,为之后成为今年最具影响力的公链埋下伏笔。这种半中心化的模式提高了eos的运作效率,比之前的模式有很高的提高,是一种创新。币安交易所遭到攻击,黑客攻击模式改变3 月 7 日晚,币安交易所遭到黑客攻击。与以往简单粗暴的盗币不同,此次攻击,黑客进行了大量的缜密计划,潜伏许久才开始行动,最终以拉高非主流代币价格,提前做空单成功获利。在这个过程中,黑客大量抛售代币,导致绝大部分币种开始下跌,市场中不明真相的散户也开始恐慌性抛售。同时,操纵账号在 1 小时内用 1 万个比特币拉高代币 VIA 价格。在大家以为黑客要把自己手中持有的 VIA 高价卖出,换成 BTC 提现到安全的账号离场时,黑客蓦然退场。交易所还是需要提高自己额安全意识,对于漏洞进行相应的检查,以保护大家的利益FOMO 3D赌博游戏兴起首先,跟大家介绍一下这款游戏是这么玩的,网上已经有很多分析文章了,在这里,我们挑重点的说。 在这款游戏的官网(http://exitscam.me/)上,玩家可以花ETH买入一个或者多个key(钥匙)。越早买key,花的钱越少。目前(截止7月22日10:30)花0.00529188ETH可以买到一把key,而就在7月20日的15点,每1个key的价格还只有0.00124 ETH,不到两天的时间里翻了3倍多,目前仍在不断上涨中。 目前玩家已经在这款游戏里累计投入了82222.075ETH,相当于3747多万美元,奖金池里有20158.44ETH,相当于约934.8万美元 。然而关于这个游戏有一个漏洞被响马大叔提前预料到,Fomo3D被黑客黑了价值几千万的 eth,江湖传言是响马黑了奖金DAPP 开始起步,精良游戏吸引众多玩家熊市出现的第一个月,币圈开始有所转机。2017 年 cryptokitties 加密猫的爆火之后,DAPP 的发展似乎陷入沉寂。此时,投机行为暂时销声匿迹,暗自发力的 DAPP 开始显露实力。以游戏为 DAPP 主场地,制作精良的游戏吸引了更多玩家。EtherGoo 是其中一款。半挂机式的 SLG 策略游戏,和国内曾经流行的三国策略网页游戏有点相似,EtherGoo 将游戏中产生的氪金消费滚入奖池中重新分配给玩家们,受到玩家欢迎,每天流水达 100 万元。且游戏所有交互在以太坊主链运行,避免官方作弊行为。而后,制作较为精良的 Etheremon 也得到更多活跃人数,这款怪兽对战题材游戏「Etheremon」相比其他作品,制作精美了许多,基本已经具备了一款完整网页游戏的雏形。dapp的发展是很有前景的,同时也吸引了广大的开发者,大家也可以多多关注我们的dapp大赛EOS 超级节点选举为 EOS 区块链网络上的 21 个节点(以及 100 个备用节点)正常运行而举办的超级节点选举,成为行业盛会。持有 EOS Token 的用户,根据票数选定相关节点担任超级节点和备用节点。此前的预热中,多个竞选节点,接近 60 个来自中国。EOS 创始人 BM 因为第三代区块链技术成为币圈大佬,如今每天交易额接近 100 亿元,体现着业内对节点选举的热情。EOS 被看作是下一个比特币,但节点选举中,有资金背景的大佬公开拉票演说,甚至贿选,节点被财团把控成为一时难以解决的问题,社区走向也变得迷茫。并且,在过度的渲染中,主网上线被忽略。此前 5 月底,主网启动团队达成共识:只承认一条名为 EOS 的主网,社区同庆。而几天后的 EOS 主网正式上线,却无人问津。过度消费品牌已使得投资者对其失去信心。回过头看,EOS超级节点竞选可算得上一场极其成功的营销计划,通过这场竞选,EOS不仅赚足了眼球,还建立的广大的社区,吸引了一大批开发者,为其后期线上Dapp的发展奠定了坚实的基础。FCoin提出了“交易即挖矿”概念2018年6月,加密货币交易所FCoin提出了“交易即挖矿”概念,并在短时间内日交易量攀升至全球第一,引爆了交易所之间的大战。于是问题来了,“交易即挖矿”究竟是什么,为什么会产生如此大的影响力。“交易即挖矿”实际上就是一种基于平台币的个人交易手续费返还机制,严格的说在FCoin成立之前就已经有类似的玩法,比如Bibox此前就有拿出一定比例手续费收入返还给平台币持有者的机制。FCoin的“交易即挖矿”则进行了重新包装,仿照比特币挖矿的分配规则,拿出51%比例的平台币FT作为挖矿奖池,通过“挖矿(在FCoin上交易)”逐渐解锁FT,一旦51%的FT全部回馈完成,“挖矿”即自动终止。FCoin的横空出世,就如同向韭菜发射了一片二向箔,点燃了熊市的激情。同时返还手续费这一操作,吸引了很多用户,同时推动了交易所交易,是一个很好的模式。李笑来录音门李笑来在录音中主要表达了“自己投资赚钱的理念”以及“如何在链圈赚钱的方法”等概念,而其一句“傻逼们的共识也是共识”燃爆币圈,成为舆论斥责其“割韭菜吃相难看”的焦点。币圈大佬李笑来录音泄露,跌落神坛的同时,这段录音透露的币圈割韭菜内幕让人惊心。在各路文章传播的同时,李笑来泄漏的录音中一些有趣且重要的细节却被忽略。大家对于这件事情大概有这样几个解释:第一个,Ripple 和 NEO,软银和复星没看懂,投完却暴涨;李笑来操盘的Candy.ONE的合作项目 COCOS 被爆联合硬币资本收割韭菜。关于录音里的秘诀:只会投资的区块链基金没有未来,李笑来会为项目方提供除资金之外的资源;表面的和平是赚钱的必要条件,李笑来心里认为币安是傻逼,但还是找币安接盘支点的融资。每个币圈大佬都有别人无法撼动的核心能力,比如 Link VC 创始人林嘉鹏和 OKEx 的田颖关系非同一般。李笑来这么一说伤了广大投资者的心区块链信息技术媒体封杀8 月掀起的区块链信息利箭行动,自媒体被大量封号,腾讯、百度、微博等 社交信息平台联手,全网封杀「All In」「一夜暴富」的故事。更关键的是,国家互金举报平台将代币发行融资纳入举报范围,币圈部分媒体为低底线付出代价,区块链媒体也由此嗅到危险的味道。舆论唱衰时,真正的业内人开始思考区块链到底能干什么,空头模型的效果怎样等关系行业发展的问题。区块链目前的较广为人知的应用体现在三方面:第一,比特币,没能成为货币而变成名义上的电子黄金。第二,Token(通证),一种代表资本市场的运作方式的权益。第三,一种虚拟资产,以加密猫为代表的不可交换 (non-fungible) 资产。泡沫已经破裂,区块链的项目已经趋于理性化的过程当中,我们应该专注于区块链的落地应用,大家多多关注fibos比特币大跌上热搜的社会影响9 月,比特币价格开启震荡模式,至中旬已有三轮明显的震荡。第一次,比特币价格在 2 小时内暴跌 5.4%,此波下跌并未像往常一样短时间恢复,至次日早晨,比特币在一小时内暴跌 7.1% 后进入横盘状态。隔日,再次在凌晨出现短时下跌 3.1% 的情况。作为加密数字货币的主心骨,短时间内的多次下跌使得投资者和从业者的信心受挫,同时巨额资金的流入和流出也加剧持有者的恐慌。甚至,# 比特币暴跌 # 的话题又一次成为社会热门话题,登陆微博热门话题。在众多评论中,普通群众透露出的关键词为「骗局」、「传销」、「传销」,相关利益者则更关心显卡、矿机,记忆背后是否存在操纵价格的问题。不同角度的评论中,透露出加密数字货币货币两级市场认知,其背后,是现行市场的不成熟。广大投资者也要理性,比特币大跌也是一种金融现象,大家也要关注价值投资,理性对待USDT 崩溃与稳定币项目出现10 月 15 日,最早出现的稳定币 USDT 突然暴跌 8%。在此前多次加密数字货币的大幅涨跌中,USDT 死守「稳定」特性,成为币币交易的中介币。此次下跌使得稳定币的二级市场信誉受到打击,托管 USDT(Tether)现金的银行 Noble Bank 半月前被曝面临运营危机,频临倒闭。Bitfinex 被用户质疑失去偿付能力,「现金提取出现问题,用户的数字资产被挪用」等消息不胫而走,引发用户信任危机。此次暴跌正逢稳定币概念流行。9 月初美国先后批准交易所 Gemini 和区块链创业公司 Paxos 发行 GUSD 和 PAX 稳定币,之其他交易所相继入局。与美元、英镑等货币挂钩的稳定币成为一时追捧的对象。稳定币项目大量出现,会是18年底到明年的一个新的热门模式,同时我们的稳定币 FOD 也将上线,希望大家多多关注BTC分叉币BCH再次分叉分叉原因:扩容&内讧 曾经,澳本聪和吴忌寒共同为BCH的诞生立下了汗马功劳。 然而,不到一年,双方共识破裂。其分歧主要围绕在:是否需要继续扩容,是回归比特币路线还是顺应加密市场的发展,当然更重要的还有背后的矿池利益纠纷,通过硬分叉,BCH的运营方将由双方的矿工和算力决定。 双方各自有理,至今僵持不下。 分叉影响几何? 如今,在比特币这个庞大的生态体系里,矿工、交易所、应用程序、用户、投资者早已成为环环相扣、无法分割的一部分。任何一个环节出问题,都将影响到整个生态体系的稳定。 所以,尽管每一次分叉是不同势力之间的博弈,但更多的是对资金和技术的消耗。 当年BTC分叉前后造成的最直接影响就是价格的波动。 据华尔街见闻行情显示,从2017年7月15日到2017年8月15日期间,BTC的价格从1914美元上升到4387美元,涨幅高达129%; 而由BTC分叉出来的BCH,自分叉日开始,价格则连连败退,到8月中旬,价格从1213美元的高点下落至298美元,跌幅高达75%以上。BCH分叉导致价格下跌,合作者应尽量维护好共识,寻求一个更好的解决办法国内外数字货币认知趋势11 月初,央行研究院发布研究报告,近 2 万字的论文围绕着「区块链能做什么、不能做什么」展开。作者从经济学角度研究区块链的功能,从想对宏观的层面对 Token 范式、区块链共识与信任、智能合约、应用方向、治理问题、安全性等热点话题进行分析。央行研究院对区块链应用场景的研究仿佛给市场打了一剂强心剂,但与此同时,国内外对区块链市场的特定信息传播打击力度也在加大。11 月中旬,国内封号潮再次来临,BABI 财经、核财经无法打开,吴解区块链甚至被二度封号。国外 Apple 下架 iTunes 商店的加密数字货币新闻栏目,Twitter 、Medium 的知名分析师被封号。熊市给了市场净化的空隙,拉盘喊单变得越来越不被市场认可,或许回归加密数字货币认知普及,是最保险的求生办法。市场也应该对数字货币加强市场普及以及认知规范,数字货币还是很有前景的文末附上官方地址~~~https://fibos.io/FIBOS 是一个创造和发展区块链应用生态的平台,让你轻松创建属于自己的价值网络,帮助开发者和创业者一步进入区块链世界。https://dev.fo/JavaScript 开发 + BANCOR 协议智能通证 + 开发者服务,FIBOS 平台实现了快速开发、快速部署和稳定且流动的通证体系,帮助开发者一步进入区块链时代。搜索关注公众号「FIBOS社区」,第一时间获取技术干货! ...

December 21, 2018 · 2 min · jiezi

EOS账户如何工作,我们又怎样获得EOS账号?

EOS账户的工作方式是什么?帐户是存储在区块链中的人类可读名称。它可以由个人或一群人拥有,具体的取决于权限配置。需要一个帐户来将交易转移或推送到区块链。——EOSIO WikiEOS账户如何工作每个EOS帐户长度为12个字符(除非它是高级帐户,稍后将对其进行说明)并包含字符a-z和1-5。EOS帐户由2个密钥组成,即active密钥和owner密钥。active密钥可用于转移资金,为区块生产者投票,购买ram等。owner密钥显示帐户的所有权,并且可以对帐户的所有权进行任何更改。这个密钥从安全考虑最好保持离线,因为在EOS网络上大部分工作不需要用它来做。可以在帐户内设置各种其他权限,其中一些将在下面说明。多签名帐户能够更改EOS帐户中的权限意味着可以创建多签名帐户。多重签名意味着可以要求多个人授权帐户中的某些操作。下面将举例说明。在上面的示例中,该帐户是一个多签名帐户,有3个用户。更改帐户的所有者权限需要权重阈值2。Bob和Stacy都有1的权重,因此为了对帐户的所有者权限进行任何更改,Bob和Stacy都必须同时授权更改才行。要发送交易,购买RAM,投票给生产者,或做任何需要活动密钥的事情,需要权重阈值为1。这意味着Bob和Stacy都可以在未经对方许可的情况下执行上述操作。第三个许可是可选的,也是EOS的可能性之一。在此示例中,发布表示在特定博客上发布文章的权限。发布文章所需的权重阈值是2。Bob和Stacy的权重为2,而另一个帐户的权重为1。这意味着如果Bob和Alice想要发布文章,他们不需要某人的许可否则这样做,但如果其他帐户需要Bob或Stacy的许可才能发布文章。如何创建EOS帐户?有多种方法可以创建EOS帐户,例如使用cleos或使用其中一个可用的工具包。对于本指南,我们将使用此工具包。要创建新的EOS帐户,你需要使用现有的EOS帐户。如果你没有现有帐户,则可以使用为你创建帐户的工具。使用这些工具需要你自担风险,并始终研究是否可以信任工具。首先,你必须下载Scatter,一个浏览器扩展。你可以在这里获得Scatter。按照有关如何设置Scatter帐户和登录Scatter扩展的说明进行操作。之后转到工具包并连接你现有的EOS帐户。连接帐户后,可以转到“创建帐户”并填写空白处。你可以使用现有密钥对作为owner公钥和active公钥,也可以在“密钥对”选项卡下的hash中生成新密钥对。我们建议不要更改net stake,CPU stake和RAM purchase,因为你可以在创建账户后随时获得更多代币并购买更多内存。请注意以下信息可能已经过时,因为创建帐户的费用已降低始终确保你用于创建新帐户的EOS帐户包含足够的EOS来创建新帐户。创建新帐户的成本(使用上述设置)可以通过以下方式计算:(当前RAM价格/Kb)*8+0.1+0.1=创建新帐户所需的最低EOS数量高级帐户名称大多数EOS帐户的帐户名称长度为12个字符,但是有一种方法可以获得短于12个字符的帐户名称。这些帐户名称称为高级帐户名称,每天只授予1个高级帐户名称。该名称每天授予最高出价者。就像有各种方式购买RAM,放弃您的EOS等等,有各种方式来竞标高级帐户名称。下面我们将解释如何使用工具包竞标高级名称。我们正在使用此工具包。首先,你需要使用Scatter连接你的EOS帐户(请参阅上面的说明)。连接帐户后,你可以开始对名称进行出价。在出价高级帐户名称之前,你需要记住一些事项。如果你对高级帐户名称进行出价,则你的EOS会被锁定,如果你的出价过高,只能获得返回来的EOS。这可能需要很长时间(并且可能永远不会以低出价发生),因此请始终确保你的出价是切合实际的。要查看当前的高级名称出价,可以访问此网站。======================================================================分享一些以太坊、EOS、比特币等区块链相关的交互式在线编程实战教程:EOS教程,本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。java以太坊开发教程,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。python以太坊,主要是针对python工程师使用web3.py进行区块链以太坊开发的详解。php以太坊,主要是介绍使用php进行智能合约开发交互,进行账号创建、交易、转账、代币开发以及过滤器和交易等内容。以太坊入门教程,主要介绍智能合约与dapp应用开发,适合入门。以太坊开发进阶教程,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。C#以太坊,主要讲解如何使用C#开发基于.Net的以太坊应用,包括账户管理、状态与交易、智能合约开发与交互、过滤器和交易等。java比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Java代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Java工程师不可多得的比特币开发学习课程。php比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Php代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Php工程师不可多得的比特币开发学习课程。tendermint区块链开发详解,本课程适合希望使用tendermint进行区块链开发的工程师,课程内容即包括tendermint应用开发模型中的核心概念,例如ABCI接口、默克尔树、多版本状态库等,也包括代币发行等丰富的实操代码,是go语言工程师快速入门区块链开发的最佳选择。汇智网原创翻译,转载请标明出处。这里是原文EOS账户如何工作,我们怎样获得?

December 19, 2018 · 1 min · jiezi

剥开区块链的坚果——FIBOS远航分享

12月16日下午,BCCN南京区块链社群联盟在南京审计大学举办主题为“南京区块链社群联盟高校行”的活动。FIBOS 团队金牌讲师远航在活动中对区块链的形成及发展做了深入浅出的分享。同学们对远航解析的区块链共识机制,FIBOS 智能合约以及 FIBOS 较 EOS 的优越性非常感兴趣,纷纷举手与远航老师互动。远航讲师曾就读于加州大学河滨分校(University of California, Riverside)伯恩斯工程学院,攻读计算机科学专业硕士学位,并在2014年荣获第七届英特尔杯全国大学生软件创新大赛二等奖,2015年荣获微软创新杯全球科技大赛(Imagine Cup)中国区二等奖,2016年荣获数学建模美赛全球一等奖。远航在加州很早就关注区块链的相关话题,对区块链有着独到的见解。活动中,远航在“剥开区块链的坚果”主题分享中介绍了链是如何形成的。1、交易发起方【构造交易】、【签名】、【广播】到区块链P2P网络中 2、区块链网络中的【矿工】接收到交易 3、【矿工】将交易打包到自己构建的新的【备选区块】中,并将自己的备选区块广播 4、【矿工】通过【共识算法】完成备选区块的共识 5、【共识】后的区块被添加到链上 6、【矿工】执行区块中的所有交易 7、执行完成, 交易的参与方可以查询到交易执行的结果信息 【区块链浏览器、钱包】除此之外,远航普及了EOS,FIBOS以及智能合约的概念。分享中,远航向大家展示了 FIBOS相较于EOS的优越性。不仅如此,FIBOS同时也解决了环境部署难、开发门槛高、测试工具原始、迭代周期长、生态残缺、运行成本高、合约难以审计的问题,让更多的开发者可以进入到区块链这个大家庭中。

December 18, 2018 · 1 min · jiezi

EOS智能合约安全终极指南

EOS智能合约安全终极指南。当世界上最大的ICO,EOS于2018年6月推出时,加密社区变得持怀疑态度,并且由于软件错误而被冻结了2天。但快进4个月,EOS今天占了以太网今天所做交易的两倍以上。通过免费和更快速交易的承诺,EOS最顶级的Dapp拥有大约13,000个每日活跃用户,而以太网的最顶级Dapp只有2,000个。一些常见的智能合约漏洞几乎适用于所有平台。与以太坊一样,在EOS上编写的智能合约需要在主网上上线之前进行审核。合约中的致命错误可以在合约没有经过足够的测试时被利用。在本指南中,我们将帮助你避免在EOS上制作下一个杀手dApp的过程中常见的陷阱。在阅读本指南之前,了解有关EOS开发的一些先决条件信息非常重要,这些信息在你阅读本指南时会很方便。了解C++是必须的。开始智能合约开发的最佳位置是EOSIO自己的文档。ABI调用处理extern “C” {void apply(uint64_t receiver, uint64_t code, uint64_t action) { class_name thiscontract(receiver); if ((code == N(eosio.token)) && (action == N(transfer))) { execute_action(&thiscontract, &class_name::transfer); return; } if (code != receiver) return; switch (action) { EOSIO_API(class_name, (action_1)(action_n))}; eosio_exit(0);}}上面是修改后的ABI调用程序的示例代码。如下所示的更简单的ABI调用程序用于简化合约的操作处理。EOSIO_ABI( class_name, (action_1)(action_n) );ABI调用程序/交易处理程序允许合约收听传入的eosio.token交易时间,以及与智能合约的正常交互。为了避免异常和非法调用,绑定每个键操作和代码以满足要求是很重要的。一个例子是由于他们的ABI转发源代码中的错误而发生在dApp EOSBet Casino上的黑客攻击 。if( code == self || code == N(eosio.token) ) {TYPE thiscontract( self );switch( action ) {EOSIO_API( TYPE, MEMBERS )}}上面检查ABI转发源代码的apply动作处理程序允许攻击者完全绕过eosio.token::transfer()函数,并在放置之前直接调用contract::transfer()函数而不将EOS转移到合约中。打赌。对于损失,他没有得到任何报酬,但一无所获。然而,对于胜利,他从合约中支付了真正的EOS。他们通过在传入操作请求合约之前添加eosio.token合约转移操作检查来修复上述错误。if( code == self || code == N(eosio.token) ) {if( action == N(transfer) ){eosio_assert( code == N(eosio.token), “Must transfer EOS”);}TYPE thiscontract( self );switch( action ) {EOSIO_API( TYPE, MEMBERS )}}使用语句require_auth(account)非常重要;进入只需要授权帐户才能执行的操作。require_auth(_self);用于仅授权合约的所有者签署交易。操作中的授权void token::transfer( account_name from, account_name to, asset quantity){ auto sym = quantity.symbol.name(); require_recipient( from ); require_recipient( to ); auto payer = has_auth( to ) ? to : from; sub_balance( from, quantity ); add_balance( to, quantity, payer );}上面的示例代码允许任何人调用该操作。要解决它,请使用require_auth(from),声明授权付款人调用该行动。尽量避免修改eosio.token合约最近一位白帽黑客因其eosio.token合约中的方法调用问题而设法获得了10亿美元的dapp代币。Dapp Se7ens(现在处于非活动状态)在eosio.token合约中声明了一种新方法,用于将其代币空投到用户帐户中。合约没有反映eosio.token合约的问题或转移操作的变化,因此资金神奇地出现在用户的帐户上。其次,他们忘记在转移之前验证方法中的金额,这允许黑客在此过程中索取10亿个代币。除了更改最大供应和代币符号之外,建议避免为自定义函数修改它,因为eosio.token合约中的错误可能是致命的。为了便于安全地进行空投,将空投代币转移到一个单独的帐户并从那里分发。修改多索引表属性EOS当前将数据存储在共享内存数据库中,以便跨操作共享。struct [[eosio::table]] person { account_name key; std::string first_name; std::string last_name; std::string street; std::string city; std::string state; uint64_t primary_key() const { return key; } };typedef eosio::multi_index<N(people), person> address_index;上面的示例代码创建了一个名为people的multi_index表 ,该表基于使用struct person的该表的单行的数据结构。部署后,EOS目前不允许修改表属性。eosio_assert_message断言失败将是将被抛出的错误。因此,在部署表之前需要完全考虑属性。否则,需要创建具有不同名称的新表,并且在从旧表迁移到新表时需要特别小心。如果不这样做可能会导致数据丢失。数值外溢检查在进行算术运算时,如果没有足够负责地检查边界条件,则值可能会溢出,从而导致用户资产丢失。void transfer(symbol_name symbol, account_name from, account_names to, uint64_t balance) {require_auth(from);account fromaccount;eosio_assert(is_balance_within_range(balance), “invalid balance”);eosio_assert(balance > 0, “must transfer positive balance”); uint64_t amount = balance * 4; //Multiplication overflow}在上面的示例代码中,使用uint64_t表示用户余额可能会在值乘以时导致溢出。因此,尽量避免使用uint64_t来表示余额并对其执行算术运算。使用eosiolib中定义 的asset结构进行操作,而不是处理溢出条件的精确余额。考虑合约中的假设在执行合约时会有假设需要断言。如果断言失败,使用eosio_assert将事先处理条件并停止执行特定操作。举个例子:void assert_roll_under(const uint8_t& roll_under) { eosio_assert(roll_under >= 2 && roll_under <= 96, “roll under overflow, must be greater than 2 and less than 96”); }上面的断言语句假设roll_under整数大于2且小于96.但如果不是,则抛出上述消息并停止执行。没有发现像上面这样的局部问题可能会成为规则制定的全局灾难。生成正确随机数如果没有准确完成,在EOS区块链上生成正确的随机数仍然存在风险。如果没有正确地做到这一点,将导致对手预测结果,在整个过程中对整个系统进行游戏。像Oracalize.it这样的服务可以提供来自外部源的随机数,但它们很昂贵并且可能出现单点故障。人们过去曾使用Blockchain的上下文变量(块编号,块时间戳等)来生成以太坊智能合约中的随机数,这只是在游戏中使用。为了正确地进行生成,程序必须提供一种单一方无法单独控制的组合随机性。目前最好的方法之一是Dan Larimar自己生成随机数时建议的方法。string sha256_to_hex(const checksum256& sha256) { return to_hex((char*)sha256.hash, sizeof(sha256.hash));}string sha1_to_hex(const checksum160& sha1) { return to_hex((char*)sha1.hash, sizeof(sha1.hash));}template <class T>Inline void hash_combine(std::size_t& seed, const T& v) { std::hash<T> hasher; seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);}上面的示例代码给出了1到100之间的优化随机数生成.seed1是种子,seed2是上面的用户种子。作为参考,Dappub和EOSBetCasino开放了他们的完整合约,随机数发生器实现了玩家和开发商之间的公平骰子游戏。uint8_t compute_random_roll(const checksum256& seed1, const checksum160& seed2) { size_t hash = 0; hash_combine(hash, sha256_to_hex(seed1)); hash_combine(hash, sha1_to_hex(seed2)); return hash % 100 + 1; }EOSBet最近再次遭到65,000EOS的攻击,当一个对手欺骗他们的eosio.token合约时,只要他在自己的钱包之间进行交易,就将EOS送到他的钱包。eosio.token合约代码 通知EOS代币的发送者和接收者有传入代币。为了模仿这种行为并促进黑客攻击,对手创建了两个帐户,让我们假设A和B。A与智能合约的操作有声明require_recipient(N(eosbetdice11))。当A通过操作调用促进了从A到B的交易时,它通知合约中的转移功能,就好像该呼叫来自eosio.token合约一样。由于EOS没有真正转移到合约中,每当黑客输掉赌注时,他什么都没有丢失,但是在赢得赌注时他获得了奖励。因此,仅检查合约名称和操作名称是不够的。检查合约中的通知为了缓解这个问题,该函数应检查合约是否确实是代币的接收者。eosio_assert(transfer_data.from == _self || transfer_data.to == _self, “Must be incoming or outgoing transfer”);在EOS上制定智能合约时应遵循的最佳做法是什么?错误是任何软件不可避免的一部分。它的后果在去中心化的环境中被放大,特别是如果它涉及价值交易。除了上面讨论的EOS特定保护措施之外,以下是新智能合约开发人员应该记住的一些一般预防措施和最佳实践:在主网上发布之前,始终独立于第三方智能合约审计公司审计合约。在发布到testnet之前,进行必要的Caveman调试(当前调试合约的唯一方法)。EOSIO文档有一个很好的指南。设置提款限额转移率,避免主网启动初期出现过多损失。有白帽黑客负责任披露的bug赏金计划。当检测到错误时,有一个killswitch来冻结合约。为了实现它,我们在multi_index表中保留一个标志。我们使用只能由合约所有者调用的操作来设置标志。然后我们检查每个公共行动是否将标志设置为冻结。下面给出了该函数的示例实现。struct st_frozen { uint64_t frozen;};typedef singleton<N(freeze), st_frozen> tb_frozen;tb_frozen _frozen;uint64_t getFreezeFlag() { st_frozen frozen_st{.frozen = 0}; return _frozen.get_or_create(_self, frozen_st);}void setFreezeFlag(const uint64_t& pFrozen) { st_frozen frozen_st = getFreezeFlag(); frozen_st.frozen = pFrozen; _frozen.set(frozen_st, _self);}// public Actionvoid freeze() { require_auth(_self); setFreezeFlag(1);}// public Actionvoid unfreeze() { require_auth(_self); setFreezeFlag(0);}// any public actionvoid action(…) { eosio_assert(getFreezeFlag().frozen == 1, “Contract is frozen!”); …}随时了解库中的安全性增强或平台上的漏洞披露。必要时立即更新库。至少开源合约代码,以便在项目中保持公平性,独立开发人员可以更快地发现错误。EOS智能合约安全:结论自EOS推出仅仅5个月,它已经超出了预期。它所取得的DPOS,可变智能合约,21个采矿节点等,当然受到权力下放极端主义者的严厉批评。然而,考虑到平台今天提供的可扩展性,它并没有阻止基于以太坊的dApp转向EOS。无论是EOS还是以太坊赢得战争还有待确定,但EOS肯定赢得了这场战斗。它将保持不变,直到以太坊设法达到运行“世界计算机”所需的世界所需的可扩展性。======================================================================分享一些以太坊、EOS、比特币等区块链相关的交互式在线编程实战教程:EOS教程,本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。java以太坊开发教程,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。python以太坊,主要是针对python工程师使用web3.py进行区块链以太坊开发的详解。php以太坊,主要是介绍使用php进行智能合约开发交互,进行账号创建、交易、转账、代币开发以及过滤器和交易等内容。以太坊入门教程,主要介绍智能合约与dapp应用开发,适合入门。以太坊开发进阶教程,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。C#以太坊,主要讲解如何使用C#开发基于.Net的以太坊应用,包括账户管理、状态与交易、智能合约开发与交互、过滤器和交易等。java比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Java代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Java工程师不可多得的比特币开发学习课程。php比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Php代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Php工程师不可多得的比特币开发学习课程。tendermint区块链开发详解,本课程适合希望使用tendermint进行区块链开发的工程师,课程内容即包括tendermint应用开发模型中的核心概念,例如ABCI接口、默克尔树、多版本状态库等,也包括代币发行等丰富的实操代码,是go语言工程师快速入门区块链开发的最佳选择。汇智网原创翻译,转载请标明出处。这里是原文EOS智能合约安全终极指南 ...

December 17, 2018 · 2 min · jiezi

EOSIO 指南(了解ABI文件)

了解ABI文件介绍之前,你使用提供的ABI文件部署了eosio.token合约,本教程将概述ABI文件如何与eosio.token合约相关联。可以使用eosio.cdt提供的eosio-cpp实用程序生成ABI文件,但是,有几种情况可能导致ABI的生成出现故障或完全失败,高级C++模式可以将其提升,自定义类型有时会导致ABI生成的问题,因此,你必须了解ABI文件的工作原理,以便在必要时进行调试和修复。什么是ABI?应用程序二进制接口(ABI)是一个基于JSON的描述,介绍如何在JSON和二进制表示之间转换用户操作,ABI还描述了如何将数据库状态转换为JSON或从JSON转换,通过ABI描述合约后,开发人员和用户将能够通过JSON无缝地与你的合约进行交互。安全说明执行交易时可以绕过ABI,传递给合约的消息和操作不必符合ABI,ABI是一个指南,而不是看门人。创建一个ABI文件从空的ABI开始,将其命名为eosio.token.abi{ “version”: “eosio::abi/1.0”, “types”: [], “structs”: [], “actions”: [], “tables”: [], “ricardian_clauses”: [], “abi_extensions”: [], “___comment” : “"}typesABI允许任何客户端或接口解释甚至为你的合约生成GUI,为了使其以一致的方式工作,请描述在ABI中需要描述的任何公共操作或结构中用作参数的自定义类型。内置类型EOSIO实现了许多自定义内置类型,不需要在ABI文件中描述内置类型,如果你想熟悉EOSIO的内置类型,它们定义在这里。{ “new_type_name”: “name”, “type”: “name”}ABI现在看起来像这样:{ “version”: “eosio::abi/1.0”, “types”: [{ “new_type_name”: “name”, “type”: “name” }], “structs”: [], “actions”: [], “tables”: [], “ricardian_clauses”: [], “abi_extensions”: []}structs暴露于ABI的结构也需要描述,通过查看eosio.token.hpp,可以快速确定公共操作使用了哪些结构,这对下一步尤为重要。JSON中的结构对象定义如下所示:{ “name”: “issue”, //The name “base”: “”, //Inheritance, parent struct “fields”: [] //Array of field objects describing the struct’s fields. }fields{ “name”:”", // The field’s name “type”:"" // The field’s type}在eosio.token合约中,有许多结构需要定义,请注意,并非所有结构都是显式定义的,有些结构对应于操作的参数,以下是需要对eosio.token合约进行ABI描述的结构列表。隐式结构以下结构是隐式的,因为结构从未在合约中显式定义,查看create操作,你将找到两个参数,类型为name的issuer和asset类型的maximum_supply,为简洁起见,本教程不会分解每个结构,但应用相同的逻辑,你将得到以下结果:create{ “name”: “create”, “base”: “”, “fields”: [ { “name”:“issuer”, “type”:“name” }, { “name”:“maximum_supply”, “type”:“asset” } ]}issue{ “name”: “issue”, “base”: “”, “fields”: [ { “name”:“to”, “type”:“name” }, { “name”:“quantity”, “type”:“asset” }, { “name”:“memo”, “type”:“string” } ]}retire{ “name”: “retire”, “base”: “”, “fields”: [ { “name”:“quantity”, “type”:“asset” }, { “name”:“memo”, “type”:“string” } ]}transfer{ “name”: “transfer”, “base”: “”, “fields”: [ { “name”:“from”, “type”:“name” }, { “name”:“to”, “type”:“name” }, { “name”:“quantity”, “type”:“asset” }, { “name”:“memo”, “type”:“string” } ]}close{ “name”: “close”, “base”: “”, “fields”: [ { “name”:“owner”, “type”:“name” }, { “name”:“symbol”, “type”:“symbol” } ] }显式结构这些结构是显式定义的,因为它们是实例化多索引表的条件,描述它们与定义如上所示的隐式结构没有什么不同。account{ “name”: “account”, “base”: “”, “fields”: [ { “name”:“balance”, “type”:“asset” } ]}currency_stats{ “name”: “currency_stats”, “base”: “”, “fields”: [ { “name”:“supply”, “type”:“asset” }, { “name”:“max_supply”, “type”:“asset” }, { “name”:“issuer”, “type”:“account_name” } ]}actions操作的JSON对象定义如下所示:{ “name”: “transfer”, //The name of the action as defined in the contract “type”: “transfer”, //The name of the implicit struct as described in the ABI “ricardian_contract”: "" //An optional ricardian clause to associate to this action describing its intended functionality.}通过聚合eosio.token合约头文件中描述的所有公共函数来描述eosio.token合约的操作。然后根据之前描述的结构描述每个操作的类型,在大多数情况下,函数名称和结构名称将相等,但不必相等。下面是链接到其源代码的操作列表,其中提供了示例JSON,以了解每个操作的描述方式。create{ “name”: “create”, “type”: “create”, “ricardian_contract”: “"}issue{ “name”: “issue”, “type”: “issue”, “ricardian_contract”: “"}retire{ “name”: “retire”, “type”: “retire”, “ricardian_contract”: “"}transfer{ “name”: “transfer”, “type”: “transfer”, “ricardian_contract”: “"}close{ “name”: “close”, “type”: “close”, “ricardian_contract”: “"}tables描述表,这是表的JSON对象定义:{ “name”: “”, //The name of the table, determined during instantiation. “type”: “”, //The table’s corresponding struct “index_type”: “”, //The type of primary index of this table “key_names” : [], //An array of key names, length must equal length of key_types member “key_types” : [] //An array of key types that correspond to key names array member, length of array must equal length of key names array.}eosio.token合约实例化两个表,accounts和stats。accounts表是一个i64索引,基于account struct,有一个uint64作为它的主键。以下是如何在ABI中描述accounts表。{ “name”: “accounts”, “type”: “account”, // Corresponds to previously defined struct “index_type”: “i64”, “key_names” : [“primary_key”], “key_types” : [“uint64”]}stat表是一个i64索引,基于currenct_stats struct,有一个uint64作为它的主键。以下是如何在ABI中描述stat表。{ “name”: “stat”, “type”: “currency_stats”, “index_type”: “i64”, “key_names” : [“primary_key”], “key_types” : [“uint64”]}你会注意到上面的表格具有相同的“key name”,将键命名为相似的名称是象征性的,因为它可能暗示一种主观关系,与此实现一样,这意味着可以使用任何给定的值来查询不同的表。把它们放在一起最后,一个准确描述eosio.token合约的ABI文件。{ “version”: “eosio::abi/1.0”, “types”: [ { “new_type_name”: “name”, “type”: “name” } ], “structs”: [ { “name”: “create”, “base”: “”, “fields”: [ { “name”:“issuer”, “type”:“name” }, { “name”:“maximum_supply”, “type”:“asset” } ] }, { “name”: “issue”, “base”: “”, “fields”: [ { “name”:“to”, “type”:“name” }, { “name”:“quantity”, “type”:“asset” }, { “name”:“memo”, “type”:“string” } ] }, { “name”: “retire”, “base”: “”, “fields”: [ { “name”:“quantity”, “type”:“asset” }, { “name”:“memo”, “type”:“string” } ] }, { “name”: “close”, “base”: “”, “fields”: [ { “name”:“owner”, “type”:“name” }, { “name”:“symbol”, “type”:“symbol” } ] }, { “name”: “transfer”, “base”: “”, “fields”: [ { “name”:“from”, “type”:“name” }, { “name”:“to”, “type”:“name” }, { “name”:“quantity”, “type”:“asset” }, { “name”:“memo”, “type”:“string” } ] }, { “name”: “account”, “base”: “”, “fields”: [ { “name”:“balance”, “type”:“asset” } ] }, { “name”: “currency_stats”, “base”: “”, “fields”: [ { “name”:“supply”, “type”:“asset” }, { “name”:“max_supply”, “type”:“asset” }, { “name”:“issuer”, “type”:“name” } ] } ], “actions”: [ { “name”: “transfer”, “type”: “transfer”, “ricardian_contract”: "” }, { “name”: “issue”, “type”: “issue”, “ricardian_contract”: "” }, { “name”: “retire”, “type”: “retire”, “ricardian_contract”: "” }, { “name”: “create”, “type”: “create”, “ricardian_contract”: "” }, { “name”: “close”, “type”: “close”, “ricardian_contract”: "” } ], “tables”: [ { “name”: “accounts”, “type”: “account”, “index_type”: “i64”, “key_names” : [“currency”], “key_types” : [“uint64”] }, { “name”: “stat”, “type”: “currency_stats”, “index_type”: “i64”, “key_names” : [“currency”], “key_types” : [“uint64”] } ], “ricardian_clauses”: [], “abi_extensions”: []}代币合约未涵盖的情况向量在ABI文件中描述向量时,只需使用[]附加类型,因此如果需要描述权限级别的向量,你可以这样描述:permission_level[]。结构基础这是一个很少使用的属性,值得一提,你可以使用base ABI结构属性来引用另一个继承结构,只要该结构也在同一个ABI文件中描述,如果你的智能合约逻辑不支持继承,Base将不执行任何操作或可能抛出错误。你可以在系统合约源代码和ABI中看到正在使用的base的示例。此处未涵盖额外的ABI属性为简洁起见,此处省略了ABI规范的一些属性,但是,有一个待定的ABI规范将完整地概述ABI的每个属性。李嘉图条款李嘉图条款描述了特定行为的预期结果,它也可用于在发件人和合约之间建立条款。ABI扩展一个通用的“面向未来”的层,允许旧客户端跳过解析扩展数据的“块”,目前,此属性尚未使用,将来,每个扩展在该向量中都有自己的“块”,以便旧客户端跳过它,以及了解如何解释它的新客户端。维护每次更改结构、添加表、添加操作或向操作添加参数、使用新类型时,你都需要记住更新ABI文件,在许多情况下,更新ABI文件失败不会产生任何错误。故障排除表不返回任何行检查你的表是否在GLOSSARY:ABI文件中准确描述,例如,如果使用cleos在具有格式错误的GLOSSARY:ABI定义的合约上添加表,然后从该表中获取行,则将收到空结果。当合约未能在其GLOSSARY:ABI文件中正确描述其表时,cleos在添加行或读取行时不会产生错误。上一篇:部署、发行和转移代币 ...

December 17, 2018 · 3 min · jiezi

如何在10分钟内为区块链设置EOS钱包和帐户

由于SuperNode超级节点社区建立在EOS之上,我们希望引导我们的社区成员设置EOS钱包和帐户,以便充分参与我们的生态系统。虽然设置过程可能不如其他区块链系统那么简单,但不要担心。本指南旨在帮助你在10分钟内逐步设置EOS钱包和帐户。本指南分为三个部分:使用Scatter设置EOS钱包以生成EOS公钥和私钥。将EOS公钥分配给EOS帐户。使用Scatter钱包配置EOS帐户。完成所有这些步骤后,你将成功设置EOS帐户,该帐户支持资金转帐,投票和接收基于EOS的代币(例如SNCT)等功能。第1部分:使用Scatter设置EOS钱包市场上有几个EOS钱包,但为了这个演示,我们将使用Scatter,因为它易于使用并被EOS社区广泛采用。Scatter是Google Chrome扩展程序,因此如果你目前没有使用Chrome浏览器,则需要下载Chrome。转到Google Chrome扩展程序的Scatter页面,然后点击添加到chrome即“Add to Chrome”2.单击Google Chrome右上角的Scatter徽标3.设置你选择的密码并单击新建一个账号即“create new Scatter”4.记下助记符并将所有12个单词保存在安全的位置5.单击跳过基本设置即“Skip Basic Setup”6.点击密钥对即“Key Pairs”7.单击新建“New”8.按照以下步骤生成密钥对:1).输入你喜欢的名字。2).单击生成密钥对即“Generate Key Pair”。完成此步骤后,将显示公钥和私钥。3).单击复制“Copy”并将两个密钥保存在安全位置。4).点击保存“Save”。9.钥匙对是激活的10.重复步骤7-9以创建另一个密钥对可以使用与不同权限对应的不同密钥配置EOS帐户。在EOS中,所有者和活动权限是每个帐户的标准权限。因此,在此步骤中,我们将为活动权限创建另外一个密钥对。重复步骤7-9后,你应该能够看到以下内容:第2部分:将你的EOS公共密钥分配给EOS帐户从Scatter获取公钥后,下一步是设置EOS帐户。有两种推荐方式:1.)询问拥有现有EOS帐户的朋友为你创建一个帐户。2.)使用EOS帐户生成工具。在本指南中,我们将向你展示如何使用第二个选项创建EOS帐户。我们建议使用EOS帐户创建器 EOS Account Creator,它简单明了,并支持多种付款方式。要设置帐户,需要4KB的RAM。在安装过程中,你需要在EOS中支付一小笔一次性费用。但是,与以太网每笔交易都需要付费不同的是,因此在设置帐户后,EOS不会产生后续交易费用。1.转到EOS帐户创建器,然后单击开始使用即“Get Started”。2.选择一个帐户名称获取你的EOS帐户名称时应遵守以下要求:1.)正好包含12个字符。2.)小写字符。3.)数字到5。3.提供所有者和活动公钥注意:EOS帐户设置只需要公钥。切勿将你的私钥发送给任何人。4.支付EOS Account Creator是一个方便的工具,支持所有流行的支付选项。其中,从交易账户使用EOS自然是最便宜的选择。5.按照这些说明结算付款如果你使用EOS结算付款,则支付RAM和投注后的剩余余额将记入你的帐户。6.你应该在付款完成后不到一分钟内看到确认7.转到EOS Block Explorer检查你的帐户状态由于我们使用工具来帮助创建帐户,因此检查准确性非常重要。最好的方法是直接通过EOS Block Explorer查看EOS区块链。1.)转到EOS Block Explorer并输入你的EOS帐户名称2.)检查您的余额和帐户状态3.)向下滚动并单击帐户权限即“Account Permissions”。仔细检查公钥是否正确。第3部分:使用Scatter钱包配置EOS帐户创建EOS帐户并检查区块链资源管理器后,你可以使用钱包配置EOS帐户。1.打开Scatter并点击“Identities”2.点击修改即“Edit”3.在帐户即“Account”下,选择你的有效密钥对4.单击导入即“Import”5.选择“your_eos_account_name @ active”,然后单击“使用所选帐户”6.点击保存即“Save”7.单击圆圈以检查帐户中的EOS余额恭喜!如果你已经到这里,那么你的帐户现已成功配置,你可以在适当的时候使用EOS执行大多数功能并接收SNCT之类的代币了。了解有关SuperNode社区项目的更多信息,该项目被选为2018年第四季度顶级区块链项目之一 :https://www.snct.io/分享一个EOS区块链相关的交互式在线编程实战教程:EOS教程,本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。汇智网原创翻译,转载请标明出处。这里是原文如何在10分钟内设置EOS钱包和帐户:分步指南

December 14, 2018 · 1 min · jiezi

使用EOSJS和scatter在EOS区块链上开发dApp

由于我一直在深入研究EOS dApp的开发,我看了不少好文章。在这里,我汇总了下做一些研究后得到的所有知识。在本文中,我将解释如何使用EOSJS和scatter。我假设你对智能合约以及如何在EOS区块链上部署它们有基本的了解,因为我将在本文中跳过该部分。我们在构建什么? 我们正在构建一个简单的todo dApp。我们将为CRUD(创建,读取,更新和删除)操作编写智能合约,并将使用EOSJS和scatter与已部署的合同进行交互。CRUD操作包括创建,完成,删除和获取待办事项。我们将使用Jungle Testnet来部署我们的智能合约。必备知识EOSEOSJSScatterScatter设置Scatter用于为区块链签署交易,并在不泄露密钥的情况下向应用程序提供个人信息。要设置Scatter钱包,请关注这个视频。在Scatter设置中,必须在网络中添加Jungle testnet,其中包含以下详细信息:Name: Jungle TestnetDomain or IP: dev.cryptolions.io // It might be changed, so check for the latest onePort: 38888chainId:038f4b0fc8ff18a4f0842a8f0564611f6e96e8535901dd45e43ac8691a1c4dca添加网络配置后,现在通过输入密钥对部分然后单击新建将你的私钥导入钱包。根据下图所示的表格填写关键信息。现在,您应该使用密钥对添加标识。如果没有用,请转到“身份”部分并添加或编辑现有身份。在身份部分,选择网络,然后选择密钥对,它会要求您在链网上添加与该密钥相关联的帐户。 您应该添加具有活动权限的帐户。你的scatter已全部设置好并可以在我们的dApp中使用。智能合约要部署todo智能合约,请按照本文将其部署到Jungle Testnet上。确保能够从文章中提到的命令行与Testnet进行交互。与Testnet交互我正在使用ReactJS作为前端部分。完整的逻辑和流程位于src文件夹中名为index.jsx的单个文件中。以下是配置对象:// Config for scatter and eosjsconst EOS_CONFIG = {contractName: “xyz”, // Contract namecontractSender: “xyz”, // User executing the contract (should be paired with private key)network: {protocol: “http”,blockchain: “eos”,host: “dev.cryptolions.io”,port: 38888,chainId: “038f4b0fc8ff18a4f0842a8f0564611f6e96e8535901dd45e43ac8691a1c4dca” // get this using http://dev.cryptolions.io:38888/v1/chain/get_info},eosOptions: {}};与scatter交互:import EOS from ‘eosjs’;document.addEventListener(scatterLoaded, this.onScatterLoad);onScatterLoad = () => {const scatter = window.scatter;window.scatter = null;// Here, we are connecting scatter with eosjs so that the transactions can be signed using keys present in scatterthis.eosClient = scatter.eos(EOS_CONFIG.network,EOS,EOS_CONFIG.eosOptions,EOS_CONFIG.network.protocol);// scatter object to collect the information present in wallet like accounts or public keythis.scatter = scatter;// to load the data present in our tablethis.loadTodos();};现在,在这个对象中,我们有两个引用EOSClient和scatter,我们将分别用它们与EOS区块链和钱包进行交互。我正在添加一个功能的代码,以使用EOSClient获取存储的数据(所有todos),你可以在src/index.jsx中检查其余功能:loadTodos() {this.eosClient.getTableRows({code: EOS_CONFIG.contractName,scope: EOS_CONFIG.contractName,table: “todos”,json: true}).then(data => {this.setState({ todos: data.rows });}).catch(e => {console.error(e);});}要获取帐户,请使用scatter对象的getIdentity():const { accounts } = await scatter.getIdentity({accounts: [config.EOS_CONFIG.network]});这样就ok。总结其中一个最大的优点是你无需在机器上维护钱包,scatter为我们管理一切。还有其他方法来托管钱包,但scatter对最终用户负责,开发人员不需要处理任何私人信息。github库分享一个交互式的在线编程实战,EOS智能合约与DApp开发入门:EOS教程本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。这里是原文 ...

September 27, 2018 · 1 min · jiezi