EOS跨鏈轉(zhuǎn)賬

閱讀本文前梢褐,您需要熟悉eos節(jié)點(diǎn)的操作流程屁桑,能夠使用客戶端cleos完成授權(quán)医寿、轉(zhuǎn)賬等功能,并且能夠完成自定義合約的開發(fā)蘑斧,此外靖秩,需要您對(duì)EOS源碼有著一定的理解,能夠簡(jiǎn)單地對(duì)EOS源碼進(jìn)行修改竖瘾。
操作系統(tǒng):MAC OS 10.13.x沟突,EOSIO版本號(hào):1.1.3

1 概述

? ? EOS主網(wǎng)已經(jīng)啟動(dòng)兩個(gè)月了,雖然EOS較比特幣捕传、以太坊等公鏈來(lái)說(shuō)其TPS得到了顯著的提升惠拭,但是EOS也存在一些問(wèn)題,諸如資源價(jià)格昂貴庸论、合約開銷大等职辅,為降低EOS主網(wǎng)的壓力,我們可以通過(guò)部署側(cè)鏈的方式來(lái)解決這些問(wèn)題聂示。

? ? EOS側(cè)鏈?zhǔn)侵敢粭l與EOS主網(wǎng)不同chain_id的鏈域携,同樣采用EOS的去中心化設(shè)計(jì)理念,并對(duì)于EOS目前所存在的問(wèn)題進(jìn)行了一些優(yōu)化鱼喉。為使得EOS主網(wǎng)資產(chǎn)能夠與EOS側(cè)鏈資產(chǎn)進(jìn)行相互的轉(zhuǎn)移秀鞭,首先解決主網(wǎng)與側(cè)鏈間的跨鏈轉(zhuǎn)賬問(wèn)題,本文主要介紹了一種將主鏈賬號(hào)A的EOS轉(zhuǎn)賬至側(cè)鏈賬號(hào)B的過(guò)程扛禽,側(cè)鏈B賬號(hào)向主鏈A賬號(hào)轉(zhuǎn)賬同理锋边。

名詞解釋:
(1) 主鏈/主網(wǎng):由block one與2018年6月2日啟動(dòng)的EOS網(wǎng)絡(luò),跨鏈操作時(shí)编曼,我們無(wú)法去更改主鏈的代碼宠默,只能在上面部署我們的合約;
(2) 側(cè)鏈:自發(fā)啟動(dòng)的非主鏈eos網(wǎng)絡(luò)灵巧;
(3) 同步鏈:用與同步主網(wǎng)塊的eos節(jié)點(diǎn)搀矫,我們可以使用修改過(guò)的程序
(4) 主鏈賬號(hào):主網(wǎng)上的用戶賬號(hào)
(5) 側(cè)鏈賬號(hào):側(cè)鏈上的用戶賬號(hào)
(6) 合約賬號(hào): 用于部署合約的賬號(hào),對(duì)此賬號(hào)的操作需要側(cè)鏈見(jiàn)證人的多重簽名

2 主鏈轉(zhuǎn)賬合約

? ? 首先刻肄,我們需要在主鏈上部署一條專供向跨鏈轉(zhuǎn)賬的合約瓤球,合約應(yīng)能接收以下3個(gè)參數(shù):主鏈轉(zhuǎn)賬發(fā)起賬號(hào)A,側(cè)鏈接收賬號(hào)B敏弃,轉(zhuǎn)賬金額卦羡。通過(guò)此合約,我們將賬戶A的資產(chǎn)轉(zhuǎn)移至主鏈的合約賬號(hào)M麦到。合約具體實(shí)現(xiàn)參考《EOS智能合約開發(fā)及授權(quán)
(1) 將轉(zhuǎn)賬合約部署至合約賬號(hào)M(本次實(shí)驗(yàn)中使用cactus作為合約賬號(hào))

cleos set contract cactus ~/cactus/cactus_eos/MainChain/contracts/cactus.token -p cactus

(2) 用戶需要使用該合約轉(zhuǎn)賬時(shí)绿饵,需要將自身賬號(hào)的active權(quán)限授予合約賬號(hào)的eosio.code權(quán)限

cleos set account permission zhd active '{"threshold" : 1, "keys" : [{"key":"EOS8GhCnJCnHFDUQhTmfAVun9AfKWp6Puye45uMJZNjYFeDCkc6N1","weight":1}], "accounts" : [{"permission":{"actor":"cactus","permission":"eosio.code"},"weight":1}]}' owner -p zhd@owner

?

3 通過(guò)多重簽名轉(zhuǎn)移側(cè)鏈資產(chǎn)

出于跨鏈轉(zhuǎn)賬的安全性以及區(qū)塊鏈去中心化考慮,側(cè)鏈應(yīng)選舉出若干名“見(jiàn)證人”瓶颠,當(dāng)見(jiàn)證人接收到主鏈向側(cè)鏈的轉(zhuǎn)賬時(shí)拟赊,需要向側(cè)鏈對(duì)改交易進(jìn)行簽名,只有當(dāng)一筆交易的簽名數(shù)量達(dá)到見(jiàn)證人總數(shù)的三分之二以上時(shí)粹淋,側(cè)鏈才能夠轉(zhuǎn)出側(cè)鏈合約賬號(hào)M'的資產(chǎn)給側(cè)鏈接收賬號(hào)B吸祟。

3.1 自定義多重簽名轉(zhuǎn)賬合約

  • 定義multi_index,使用表mtrans存儲(chǔ)待驗(yàn)證轉(zhuǎn)賬的簽名
//@abi table mtrans i64
struct mtrans {
    uint64_t id;
    checksum256 trx_id;
    account_name to;
    asset quantity;
    vector<account_name> confirmed;

    uint64_t primary_key() const { return id; }

    key256 by_trx_id() const { return get_trx_id(trx_id); }

    static key256 get_trx_id(const checksum256 &trx_id) {
       const uint64_t *p64 = reinterpret_cast<const uint64_t *>(&trx_id);
       return key256::make_from_word_sequence<uint64_t>(p64[0], p64[1], p64[2], p64[3]);
    }

    EOSLIB_SERIALIZE(mtrans, (id)(trx_id)(to)(quantity)(confirmed))
};

typedef eosio::multi_index<N(mtrans), mtrans,
        indexed_by<N(trx_id), const_mem_fun<mtrans, key256, &mtrans::by_trx_id> >
> mtran_index;
  • 合約中需要維護(hù)見(jiàn)證人列表
// 見(jiàn)證人可以由投票等方式選出桃移,這里不做具體說(shuō)明屋匕,直接在代碼中給出固定值
set<account_name> witness_set = {N(shengfeng), N(yuanchao), N(haonan)};
uint32_t wits_required_confs = (uint32_t) (witness_set.size() * 2 / 3) + 1;
  • 用于接收見(jiàn)證人簽名的action
/// @abi action
/**
 * @param user 見(jiàn)證人賬號(hào)
 * @param trx_id 轉(zhuǎn)賬交易id
 * @param to 轉(zhuǎn)賬對(duì)象
 * @param quantity 轉(zhuǎn)賬資產(chǎn)數(shù)
 */
void msigtrans(account_name user, checksum256 &trx_id, account_name to, asset quantity) {
   eosio_assert(witness_set.count(user) > 0, "user is not witness"); // 驗(yàn)證是否為見(jiàn)證人
   require_auth(user); // 驗(yàn)證此見(jiàn)證人的簽名

   auto idx = mtranses.template get_index<N(trx_id)>();
   auto curr_msig = idx.find(mtrans::get_trx_id(trx_id));

   if (curr_msig == idx.end()) {
      mtranses.emplace(_self, [&](auto &a) {
          a.id = mtranses.available_primary_key();
          a.trx_id = trx_id;
          a.to = to;
          a.quantity = quantity;
          a.confirmed.push_back(user);
      });
   } else {
      eosio_assert(curr_msig->to == to, "to account is not correct");
      eosio_assert(curr_msig->quantity == quantity, "quantity is not correct");
      eosio_assert(curr_msig->confirmed.size() < wits_required_confs, "transaction already excused");
      eosio_assert(std::find(curr_msig->confirmed.begin(), curr_msig->confirmed.end(), user)
                   == curr_msig->confirmed.end(), "transaction already confirmed by this account");

      idx.modify(curr_msig, 0, [&](auto &a) {
          a.confirmed.push_back(user); // 表示此見(jiàn)證人已認(rèn)可此交易
      });

      // 達(dá)到2/3+1的簽名時(shí)發(fā)起inline_action轉(zhuǎn)賬
      if (curr_msig->confirmed.size() == wits_required_confs) {
         action(
                 permission_level{_self, N(active)},
                 N(eosio.token), N(transfer),
                 std::make_tuple(_self, to, quantity, std::string("cactus transfer"))
         ).send();
      }
   }
}

3.2 給合約賬號(hào)授權(quán)

為使得合約賬號(hào)能執(zhí)行inline_action的轉(zhuǎn)賬交易,我們需要將合約賬號(hào)的active權(quán)限授予合約的eosio.code權(quán)限借杰。安全起見(jiàn)过吻,我們還應(yīng)刪除合約賬號(hào)的active(以及owner)權(quán)限。

./cleos set account permission cactus active '{"threshold":1,"keys":[],"accounts":[{"permission":{"actor":"cactus","permission":"eosio.code"},"weight":1}],"waits":[]}' owner -p cactus@owner

?

4 同步主鏈的轉(zhuǎn)賬交易

由于我們無(wú)法去修改EOS主鏈的代碼邏輯蔗衡,且我們部署的合約發(fā)生轉(zhuǎn)賬動(dòng)作時(shí)纤虽,主網(wǎng)也無(wú)法向我們發(fā)送消息,為了能夠知曉EOS主鏈上發(fā)生了交易粘都,我們應(yīng)開啟一個(gè)EOS節(jié)點(diǎn)去同步EOS的主鏈廓推,并且將不可撤銷塊的轉(zhuǎn)賬交易轉(zhuǎn)發(fā)給側(cè)鏈

4.1 同步鏈增加sync_plugin,并修改controller代碼邏輯

我們需要為同步鏈添加新的plugin以處理特定的合約action翩隧,并修改controller部分代碼來(lái)使用我們的plugin樊展,具體過(guò)程如下:

(1) 修改libraries/chain/include/eosio/chain/controller.hpp代碼,添加sync_block_transaction信號(hào)

//controller.hpp
signal<void(const signed_block_ptr&)>         pre_accepted_block;
signal<void(const block_state_ptr&)>          accepted_block_header;
signal<void(const block_state_ptr&)>          accepted_block;
signal<void(const block_state_ptr&)>          irreversible_block; // 需要用到的信號(hào)
signal<void(const transaction_metadata_ptr&)> accepted_transaction;
signal<void(const transaction_trace_ptr&)>    applied_transaction;
signal<void(const header_confirmation&)>      accepted_confirmation;
signal<void(const int&)>                      bad_alloc;

signal<void(const transaction_metadata_ptr&)> sync_block_transaction; // 額外添加的信號(hào)堆生,用于處理同步塊時(shí)接收到的交易

(2) 修改libraries/chain/controller.cpp代碼专缠,在apply_block中調(diào)用sync_block_transaction信號(hào),處理同步到的塊中的交易(只同步塊中交易淑仆,確保交易被主鏈生產(chǎn)者打包進(jìn)塊)

// controller.cpp
void apply_block( const signed_block_ptr& b, controller::block_status s ) { try {
      try {
         EOS_ASSERT( b->block_extensions.size() == 0, block_validate_exception, "no supported extensions" );
         start_block( b->timestamp, b->confirmed, s );

         transaction_trace_ptr trace;

         for( const auto& receipt : b->transactions ) {
            auto num_pending_receipts = pending->_pending_block_state->block->transactions.size();
            if( receipt.trx.contains<packed_transaction>() ) {
               auto& pt = receipt.trx.get<packed_transaction>();
               auto mtrx = std::make_shared<transaction_metadata>(pt);
               trace = push_transaction( mtrx, fc::time_point::maximum(), false, receipt.cpu_usage_us);
                    if( !trace->except ) {
                        // 使用此信號(hào) CALL sync_plugin
                        emit(self.sync_block_transaction, mtrx);
                    }
            } else if( receipt.trx.contains<transaction_id_type>() ) {
               trace = push_scheduled_transaction( receipt.trx.get<transaction_id_type>(), fc::time_point::maximum(), receipt.cpu_usage_us );
            } else {
               EOS_ASSERT( false, block_validate_exception, "encountered unexpected receipt type" );
            }

(3) 在libraries/chain/include/eosio/chain/types.hpp中添加新的object_type

enum object_type {
      null_object_type,
      account_object_type,
      account_sequence_object_type,
      /* 此處省略... */
      reversible_block_object_type,
      OBJECT_TYPE_COUNT, ///< Sentry value which contains the number of different object types
      transaction_reversible_object_type // 新添加的類型涝婉,不要忘了在文件最下面FC_REFLECT_ENUM中也要添加此類型
   };

(4) 創(chuàng)建sync_plugin,用于處理接收到的轉(zhuǎn)賬交易

  • 在plugin中注冊(cè) sync_block_transaction信號(hào)蔗怠,使用accepted_transaction處理接收到的交易
my->sync_block_transaction_connection.emplace(chain.sync_block_transaction.connect( [&](const transaction_metadata_ptr& trx) {
                my->accepted_transaction(trx);
            }));
  • 判斷交易中是否包含cactus合約中的transfer action墩弯,若包含吩跋,則將其記錄到transaction_reversible表中
void accepted_transaction(const transaction_metadata_ptr& trx) {
   auto& chain = chain_plug->chain();
   auto& db = chain.db();
   auto block_num = chain.pending_block_state()->block_num;

   for (const auto action : trx->trx.actions) {
      if (action.account == N(cactus)
          && action.name == N(transfer)) {
         const auto* existed = db.find<transaction_reversible_object, by_trx_id>(trx->id);
         if (existed != nullptr) {
            return;
         }
         const auto transaction_reversible = db.create<transaction_reversible_object>([&](auto& tso) {
             tso.block_num = block_num;
             tso.trx_id = trx->id;
             tso.data = action.data;
         });
         break;
      } 
   }
}
  • transaction_reversible表的結(jié)構(gòu)
#define DEFINE_INDEX(object_type, object_name, index_name) \
    struct object_name \
            : public chainbase::object<object_type, object_name> { \
            OBJECT_CTOR(object_name) \
            id_type id; \
            uint32_t block_num; \
            transaction_id_type trx_id; \
            action_data data; \
    }; \
    \
    struct by_block_num; \
    struct by_trx_id; \
    using index_name = chainbase::shared_multi_index_container< \
        object_name, \
        indexed_by< \
                ordered_unique<tag<by_id>, member<object_name, object_name::id_type, &object_name::id>>, \
                ordered_unique<tag<by_trx_id>, member<object_name, transaction_id_type, &object_name::trx_id>>, \
                ordered_non_unique<tag<by_block_num>, member<object_name, uint32_t, &object_name::block_num>> \
        > \
    >;
  • 在plugin中注冊(cè)irreversible_block信號(hào),使用send_transaction處理不可撤銷的交易
my->irreversible_block_connection.emplace(chain.irreversible_block.connect( [&](const block_state_ptr& irb) {
                my->send_transaction(irb);
            }));
void send_transaction(const block_state_ptr& irb) {
   auto &chain = chain_plug->chain();
   auto &db = chain.db();

   const auto &trmi = db.get_index<transaction_reversible_multi_index, by_block_num>();
   auto itr = trmi.begin();
   while (itr != trmi.end()) {
      if (itr->block_num <= irb->block_num) {
         auto data = fc::raw::unpack<cactus_transfer>(itr->data);

         // send propose or approve
         // datastr = "["zhd", "longge", "100.0000 EOS"]"
         string datastr = DATA_FORMAT(_peer_chain_account, string(itr->trx_id), string(data.to), data.quantity.to_string());
         vector <string> permissions = {_peer_chain_account};
         try {
            app().find_plugin<client_plugin>()->get_client_apis().push_action(_peer_chain_address/*側(cè)鏈地址*/,
                                                                              _peer_chain_constract/*側(cè)鏈多簽合約賬號(hào)*/,
                                                                              "msigtrans", datastr, permissions);
         } catch (...) {
            wlog("send transaction failed");
         }

         db.remove(*itr);
      }
      ++itr;
   }
}

4.2 啟動(dòng)同步鏈

sync_plugin中需配置以下參數(shù)

max-irreversible-transaction-age 接收交易的時(shí)限,防止轉(zhuǎn)發(fā)無(wú)效的過(guò)期交易
enable-send-propose 是否同步主鏈向側(cè)鏈的轉(zhuǎn)賬交易
peer-chain-address 側(cè)鏈節(jié)點(diǎn)的http地址
peer-chain-account 提交側(cè)鏈多重簽名的見(jiàn)證人賬號(hào)
peer-chain-constract 側(cè)鏈部署多重簽名合約的合約賬號(hào)
my-chain-constract 主鏈部署自定義轉(zhuǎn)賬合約的合約賬號(hào)

代碼如下

void sync_plugin::set_program_options(options_description& cli, options_description& cfg) {
        cfg.add_options()
                ("max-irreversible-transaction-age", bpo::value<int32_t>()->default_value( -1 ), "Max irreversible age of transaction to deal")
                ("enable-send-propose", bpo::bool_switch()->notifier([this](bool e){my->_send_propose_enabled = e;}), "Enable push propose.")
                ("peer-chain-address", bpo::value<string>()->default_value("http://127.0.0.1:8899/"), "In MainChain it is SideChain address, otherwise it's MainChain address")
                ("peer-chain-account", bpo::value<string>()->default_value("cactus"), "In MainChain it is your SideChain's account, otherwise it's your MainChain's account")
                ("peer-chain-constract", bpo::value<string>()->default_value("cactus"), "In MainChain it is SideChain's cactus constract, otherwise it's MainChain's cactus constract")
                ("my-chain-constract", bpo::value<string>()->default_value("cactus"), "this chain's cactus contract")
            ;
    }

在終端啟動(dòng)同步鏈命令如下引矩,client_plugin的相關(guān)配置詳見(jiàn)EOS跨鏈http通訊

nodeos --plugin eosio::sync_plugin --plugin eosio::client_plugin
--http-server-address 192.168.31.167:8889 --p2p-listen-endpoint 192.168.31.167:9878 --p2p-peer-address 192.168.31.151:9876
--config-dir nodeos2 --data-dir nodeos2
--client-private-key 5K8MzDTmBKfGWE5wDpTcpmMimHH2SzFADjmSkvJe47RWHv3nbke
--enable-send-propose --peer-chain-address http://192.168.31.144:8888 --peer-chain-account yc

?

5.發(fā)起轉(zhuǎn)賬

  • 執(zhí)行轉(zhuǎn)賬前梁丘,首先我們要確保:
    (1) 主鏈已部署eosio.token合約(僅限測(cè)試環(huán)境,官方主鏈無(wú)需自己操作)
    (2) 側(cè)鏈已部署eosio.token合約旺韭,可以進(jìn)行轉(zhuǎn)賬
    (3) 主側(cè)鏈上都具備轉(zhuǎn)賬的token類型氛谜,如SYS(EOS)

  • 主鏈賬號(hào)zhd執(zhí)行轉(zhuǎn)賬action,將100EOS轉(zhuǎn)至側(cè)鏈賬號(hào)longge

cleos -u http://192.168.31.151:9876 push action cactus transfer '["zhd", "longge", "100.0000 EOS"]' -p zhd

  • 主鏈轉(zhuǎn)賬成功信息

chaochaodeMacBook-Pro:cleos yuanchao$ ./cleos -u http://192.168.31.151:9876 push action cactus transfer '["zhd", "longge", "100.0000 EOS"]' -p zhd
executed transaction: 5f7bcf984b8a7bd026b38448963a2a14ee3660a5f2b2eeddfa2e79f297ce7823 128 bytes 14472 us
# cactus <= cactus::transfer {"from":"zhd","to":"longge","quantity":"100.0000 EOS"}
# eosio.token <= eosio.token::transfer {"from":"zhd","to":"cactus","quantity":"100.0000 EOS","memo":"cactus transfer"}
# zhd <= eosio.token::transfer {"from":"zhd","to":"cactus","quantity":"100.0000 EOS","memo":"cactus transfer"}
# cactus <= eosio.token::transfer {"from":"zhd","to":"cactus","quantity":"100.0000 EOS","memo":"cactus transfer"}
warning: transaction executed locally, but may not be confirmed by the network yet ]

  • 在側(cè)鏈上查看轉(zhuǎn)賬結(jié)果

cleos -u http://192.168.31.144:8888 get currency balance eosio.token longge

longge賬號(hào)到賬100EOS
經(jīng)過(guò)了sf区端、yc兩個(gè)賬號(hào)的確認(rèn)值漫,執(zhí)行轉(zhuǎn)賬成功
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市珊燎,隨后出現(xiàn)的幾起案子惭嚣,更是在濱河造成了極大的恐慌,老刑警劉巖悔政,帶你破解...
    沈念sama閱讀 222,681評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件晚吞,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡谋国,警方通過(guò)查閱死者的電腦和手機(jī)槽地,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,205評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)芦瘾,“玉大人捌蚊,你說(shuō)我怎么就攤上這事〗埽” “怎么了缅糟?”我有些...
    開封第一講書人閱讀 169,421評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵漩氨,是天一觀的道長(zhǎng)夜牡。 經(jīng)常有香客問(wèn)我,道長(zhǎng)咏闪,這世上最難降的妖魔是什么二鳄? 我笑而不...
    開封第一講書人閱讀 60,114評(píng)論 1 300
  • 正文 為了忘掉前任赴涵,我火速辦了婚禮,結(jié)果婚禮上订讼,老公的妹妹穿的比我還像新娘髓窜。我一直安慰自己,他們只是感情好欺殿,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,116評(píng)論 6 398
  • 文/花漫 我一把揭開白布寄纵。 她就那樣靜靜地躺著鳖敷,像睡著了一般。 火紅的嫁衣襯著肌膚如雪程拭。 梳的紋絲不亂的頭發(fā)上哄陶,一...
    開封第一講書人閱讀 52,713評(píng)論 1 312
  • 那天,我揣著相機(jī)與錄音哺壶,去河邊找鬼。 笑死蜒谤,一個(gè)胖子當(dāng)著我的面吹牛山宾,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播鳍徽,決...
    沈念sama閱讀 41,170評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼资锰,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了阶祭?” 一聲冷哼從身側(cè)響起绷杜,我...
    開封第一講書人閱讀 40,116評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎濒募,沒(méi)想到半個(gè)月后鞭盟,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,651評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡瑰剃,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,714評(píng)論 3 342
  • 正文 我和宋清朗相戀三年齿诉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片晌姚。...
    茶點(diǎn)故事閱讀 40,865評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡粤剧,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出挥唠,到底是詐尸還是另有隱情抵恋,我是刑警寧澤,帶...
    沈念sama閱讀 36,527評(píng)論 5 351
  • 正文 年R本政府宣布宝磨,位于F島的核電站弧关,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏懊烤。R本人自食惡果不足惜梯醒,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,211評(píng)論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望腌紧。 院中可真熱鬧茸习,春花似錦、人聲如沸壁肋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,699評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至猫胁,卻和暖如春箱亿,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背弃秆。 一陣腳步聲響...
    開封第一講書人閱讀 33,814評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工届惋, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人菠赚。 一個(gè)月前我還...
    沈念sama閱讀 49,299評(píng)論 3 379
  • 正文 我出身青樓脑豹,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親衡查。 傳聞我的和親對(duì)象是個(gè)殘疾皇子瘩欺,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,870評(píng)論 2 361