solidity代碼功能模塊

地址工具

用于檢測某個地址是否為合約的工具

pragma solidity ^0.4.24
library AddressUtils{
    function isContract(address addr) internal view returns(bool){
        uint256 size;
        assembly{size:=extcodesize(addr)}
//assembly 指明后面程序為內聯匯編。extcodesizs取得參數addr對應賬戶關聯地址的EVM字節(jié)碼長度。       
        return size>0;//
    }
}

這個合約是一個librray,只有一個函數isContract灯蝴,且被聲明為internal view.internal 限制這個函數只能由import這個合約內部使用;view 聲明這個函數不會改變狀態(tài)

限制子合約的余額

限制子合約以太幣余額的基礎合約

pragam solidity ^0.4.24;
contract LimitBlance{
    uint256 public limit;
    constructor(uint256 _limit) public{
        limit=_limit;
    }
    modifier limitedPayable{
        require(address(this).blance<=limit);
        _;
    }
}

缺點:這種利用modifier來限制的方式,無法限制其它合約通過selfdestruct操作中指定合約地址而引發(fā)的轉入操作鞠绰;也沒法限制沒有使用limitedPayable來聲明的合約函數進行轉入操作。

安全算術(SafeMath.sol)

對uint256類型進行算術四則運算的庫飒焦,也是最常用庫蜈膨,防止溢出。

pragma solidity ^0.4.24;
library SafeMath{
    function mul(uint256 _a, uint256 _b) internal pure returns(uint256 c){
        if (_a == 0){//a==0比a!=0便宜牺荠。原因:=只執(zhí)行了一個EVM判斷
            return 0;
        }
        c = _a * _b;
        assert(c / _a == _b);//_a*_b結果可能超過最大值翁巍,判斷有沒有溢出。return c;
    }
    
    function div(uint256 _a, uint256 _b) internal pure returns(uint256 ){
        return _a / _b;//結果不為整休雌,小數會被舍棄灶壶。}
    
    function sub(uint256 _a, uint256 _b) internal pure returns(uint256 c ){
         assert(_a >= _b);//防止下溢(2^256+_a-_b)
         return _a - _b;
    }
    
    function add(uint256 _a, uint256 _b) internal pure returns(uint256 c ){
         c= _a + _b;
         assert(c >= _b);//防止上溢((a+b)mod 2^256)
         return c;
    }
}

自省(ERC165)

這是一個向外界提供一個特定函數的基礎合約挑辆,這個函數可以用來查詢合約支持的接口(函數)例朱。

pragma solidity ^0.4.24;
interface ERC165{
    function supportsInterface(bytes64 _interfaceId)
    external  //外部函數
    view  //不會修改狀態(tài)
    returns(bool);
}//gas 消耗控制在30000以內
_interfaceId函數選擇器,是合約某個函數的標識(合約函數調用數據的前4個字節(jié))

接口查找基礎合約

pragma solidity ^0.4.24;
contract SupportsInterfaceWithLiikUp is ERC165{
    bytes4 public constant InterfaceId_ERC165 = 0x01ffc9a7;
    //0x01ffc9a7 ===bytes4(keccak256('SupportsInterface(bytes4)'))
    mapping(bytes4 => bool) internal supportsInterfaces;
    constructor()
         public
    {
    _registerInterface(InterfaceId_ERC165);
    }
    
    function _registerInterface(bytes4 _interfaceId)  
         internal
{
         require(interfaceId != 0xffffffff);
         supportsInterface[_interfaceId] = true;
     }   
}

這是一個實現了ERC165的基礎合約鱼蝉。

用一個mapping類型的狀態(tài)變量持久化地保存了一個由函數接口(函數選擇器)到布爾值的映射洒嗤。它提供了一個internal函數來注冊合約自身的接口函數,并在合約構造函數中直接注冊了ERC165接口函數supportsInterfaces魁亦。注意_registerInterface斷言基于ERC165的gas消耗渔隶。

歸屬權(Owner.sol)

這是一個用來給合約提供所屬權特性的基礎合約,這是一個非常重要的,大概也是最基礎的合約间唉。

pragma solidity ^0.4.24;
contract Owner{
    address public owner;
    
    event OwnershipRenounced(address indexed previousOwner);
    event OwnershipTransfered(
         address indexed previousOwner,
         address indexed newOwner 
);
   constract() public{
        owner = msg.sender;
   } 
   
   modifier onlyOwner() {
       require(msg.sender == owner);
       _;
   }
   
   function renounceOwner() public onlyOwner {
       emit OwnershipRenounced(owner);
       owner = address(0);//沒人再能調用聲明為onlyOwner的函數绞灼。  }
   
   function transferOwnership(address _newOwner) public onlyOwner{
       _transferOwnership(_newOwner);
   }
   
   function _transferOwnership(address _newOwner) internal{
       require(_newOwner != address(0));
       emit OwnershipTransfered(owner, _newOwner);
       owner = _newOwner;
   }   
}

這是一個非常通用的歸屬權基礎合約。由一個狀態(tài)變量來保存它的所有者地址呈野,并在構造函數中將合約創(chuàng)建人設置為合約所有者低矮。定義了兩個事件:OwnershipRenounced 用來通知外部世界所有者放棄對合約的所有權;OwnershipTransfered 用來通知外部世界合約歸屬權發(fā)生轉移被冒。

用戶角色(Roles.sol)

pragma solidity ^0.4.24;
library Roles{
    struct Role{
        mapping (address => bool) bearer;
    }
    
    function add(Role storage role, address addr)
         internal
{//添加角色
        role.bearer[addr] = true;
    }
    
    function remove(Role storage role,address addr)
         internal
{//移除角色
        role.bearer[addr] = false; 
    }
    
    function check(Role storage role,address addr)
         view
         internal
{//驗證角色
         require(has(role,addr))
    }
    
    function has(Role storage role,address addr)
         view
         internal
         returns(bool)
{//驗證角色
         return role.bearer[addr];
    }                       
}
 

定義結構體Role,其中保留一組地址到布爾值的映射军掂,也就是保留“某個地址是否是當前Role”的信息。

基于角色的訪問控制(RBAC.sol)

pragma solidity ^0.4.24;
import"./Role.sol";

contract RBAC{
    using Role for Roles.Role;
    
    mapping (string => Roles.Role) private roles;
    
    event RoleAdded(address indexed operator, string role);
   event RoleRemoved(address indexed operator, string role);
   
   function chekRole(address _operator, string _role)
        view
        public
   {
        roles[_role].check(_operator);
   }
   
   function hasRole(address _operator, string _role)
         view
         internal
         returns(bool)
    {
         return roles[_role].has(_operator);
    }
    
    function addRole(address _operator, string _role)
         internal
    {
        roles[_role].add(_operator);
        emit RoleAdded(_operator, _role);
    }
    
    function removeRole(address _operator, string _role)
         internal
    {
        roles[_role].remove(_operator);
        emit RoleRemoved(_operator, _role);
    }
    
    modifier onlyRole
    {//特定角色可用的函數修改器
        checkRole(msg.sender, _role);
        _;
    }         
}

非常重要的基礎合約昨悼』茸叮可以用來基于用戶角色進行相應的訪問控制。合約中定義了一個string到Roles.Role的private映射率触,也就是角色名稱到與角色相關聯的所有地址信息映射的對應關系终议。

超級用戶(Superuser.sol)

pragma solidity ^0.4.24;

import "./Ownable.sol";
import "./rbac.RBAC.sol";

contract Superuser is Ownable, RBAC {
       string public constant ROLE_SUPERUSER = "superuser" ;
       
       constructor() public{
            addRole(msg.sender,ROLE_SUPERUSER);
       }
       
       modifier onlySuperuser(){
            checkRole(msg.sender,ROLE_SUPERUSER);
            _;
       }
       
       modifier onlyOwnerOrSuperuser(){
            require(msg.sender == owner || isSuperuser(msg.sender));
            _;
       }
       
       function isSuperuser(address _addr)
            public
            view
            returns(bool)
{
                return hasRole(_addr, ROLE_SUPERUSER);
            }
       
       function transferSuperuser(address _newSuperuser) public onlySuperuser{
            require(_newSuperuser != address(0));
            removeRole(msg.sender, ROLE_SUPERUSER);
            addRole(msg.sender,ROLE_SUPERUSER);
       }
       //轉移合約地址
       function transferOwnership(address _newOwner) public onlySuperuser{
             _transferOwnership(_newOwner);   
}
超級用戶可用直接修改合約歸屬權恤筛,即使他不是合約的Owner.

聯系方式(Contactable.sol)

簡單地給Owner合約添加字符串附加信息的基礎合約

pragma solidity ^0.4.24;

import "./Ownable.sol";

contract contactable is Owner{
    string public contactInformation;
    function setcontactInformation(string info) onlyOwner public{
           contactInformation = info;
    } 
}

歸屬權轉移請求(Claimable.sol)

Ownable的擴展队塘,允許在做歸屬權轉移時,由新的的合約擁有者“聲明接受歸屬權”

pragma solidity ^0.4.24;

import "./Ownable.sol";

contract Claimable is Owner{
    address public pendingOwner;
    
    modifier onlypendingOwner(){
        require(msg.sender == pendingOwner);
        _;
    }
    
    function transferOwnership(address newOwner) onlyOwner public{
        pendingOwner = newOner;
    }
    
    function claimOwnership() onlypengdingOwner public{
        emit Ownershiptransferred(owner, pendingOwner);
        owner = pendingOwner;
        pendingOwner = address(0);
    }
}    

有時限的歸屬權轉移請求(DelayedClaimable.sol)

當前合約是對Claimable.sol的擴展缝呕,由當前合約所有者指定了一個接受歸屬權轉移的時間期限两曼,新的owner只有在時間期限內調用claimOwnership函數才能獲得合約的歸屬權陆馁。

這里的時間條件是區(qū)塊號(block.number)的范圍。原因:區(qū)塊鏈系統基于分布式對等網絡合愈,各個節(jié)點(客戶端)本地時間未必與UTC時間一致,所有使用區(qū)塊號這個全網共識的時間標志作為判定條件击狮。

pragma solidity ^0.4.24;

import "./Claimable.sol";

contract DelayedClaimable is Claimable{
    uint256 public end;
    uint256 public start;
    
    function setLimits(uint256 _start, uint256 _end) onlyOwner public{
        require(_start <= _end);
        end = _end;
        start = _start;
    }
    
    function claimOwnership() onlyPendingOwner public{
        requier((block.number <= end) && (block.number >= start));
        emit OwnershipTransferred(owner, pendingOwner);
        owner = pendingOwner;
        pendingOwner = address(0);
        end = 0;
    }
}

歸屬權繼承(Heritable.sol)

pragma solidity ^0.4.24;

import "./Ownable.sol";

contract Heritable is Ownable{
    address private heir_;
    uint256 private heartbeatTimeout_;
    uint256 private timeOfDeath_;
    
    event HeirChange(address indexed owner, addresss indexed newHeir);
    event OwnerHeartbeated(address indexed owner);
    event OwnerProclaimedDead(
        address indexed owener,
        address indexed heir,
        uint256 timeOfDeath
);
    event HeirOwnershipClaimed(
        address indexed previousOwner,
        addresss indexed newOwner
);
    
    modifier onlyHeir(){
        require(msg.sender == heir_);
        _;
    }
    
    constructor(uint256 _heartbeatTimeout) public{
        setHeartbeatTimeout(_heartbeatTimeout);
    }
    
    function setHeir(address newHeir) public onlyOwner{
        require(newOwner != owner);
        heartbeat();
        emit HeirChanged(owner, newHeir);
        heir_ = newHeir;
    }
    
}

合約不歸屬合約(HasNocontracts.sol)

當某個繼承Ownable合約的合約佛析,其所有者地址被設置為一個合約地址的時候,可以使用HasNoConstracts合約定義的reclaimConstract方法將其所有者地址轉移到當前合約的所有者彪蓬。

pragma solidity ^0.4.24;

import "./Ownable.sol";

contact HaoNoContracts is Ownable{
    function reclaimConstract(address constractAddr) external onlyOwner{
        Ownable constractInst = Ownable(contractAddr);
        constractInst.transferOwnership(owner);
    }
}

合約不持有以太幣(HasNoEther.sol)

對Ownable合約的拓展寸莫,來確保合約中不持有以太幣。

pragma solidity ^0.4.24;

import "./Ownale.sol";

contract HasNoEther is Ownable{
    constructer() public payable{
        require(msg.sender == 0);
    }
    
    function() external{
   }
   //將此合約余額轉給合約的擁有者
    function() reclaimEther() external onlyOwner{
        owner.transfer(address(this).balance);
    }
}

合約可找回token(CanClaimToken.sol)

將合約所持有的ERC20 token取回到合約所有者的地址档冬。

pragma solidity ^0.4.24;

import "./Ownable.sol";
import "../token/ERC20/ERC20Basic.sol";
import "../token/ERC20/SafeERC20.sol";

contract CanClaimToken is Ownable{
    using SafeERC20 for ERC20Basic;
    
   function reclaimToken(ERC20Basic token) external onlyOwner {
       uint256 balance = token.balance(this);//此合約余額
       token.safeTransfer(owner,balance);//合約擁有者轉走余額
   }   
}

合約不持有token(HasNoToken.sol)

pragma solidity ^0.4.24;

import "./CanClaimToken.sol";

contract HasNoTokens is CanReclaimToken{
    function tokenFallback(address _from, uint256 _value, bytes _data) external {
        _from;
        _value;
        _data;
       revert();//revert函數會導致EVM異常終止回退所有先前改變的狀態(tài)
    }
}

tokenFallback函數就是ERC233標準中要求接受者合約實現的一個函數膘茎,實現這個函數的合約會被認定是可以持有ERC233token的合約。

合約什么都不持有(NoOwner.sol)

pragma solidity ^0.4.24;

import "./HasNoEther.sol";
import "./HasNoToken.sol";
import "./HasNocontracts.sol";

contract NoOwner is HasNoEther, HasNoToken, HasNocontracts{
    }
 

簽名保鏢(SigmatureBouncer.sol)

pragma solidity ^0.4.24;

import "../Ownership/Ownable.sol";
import "../Ownership/rbac/RBAC.sol";
import "../ERCRecovery.sol";

contract SigmatureBouncer is Owner, RBAC {
    using ERCRecovery for bytes32;
    
    string public constant bytes32;
    uint constant METHOD_ID_SIZE = 4;
    //(簽名數據長度)32字節(jié) + (65 字節(jié)簽名的整字長度)96字節(jié)
    uint constant SIGNATURE_SIZE = 128;
    //需要提供保鏢的有效簽名
    modifier onlyValidSignture(bytes _sig)
    {
        require(isValidSignture(msg.sender, _sig));
        _;
    }
    //需要保鏢提供對某個特定函數的有效簽名
    modifier onlyValidSigntureAndMethod(bytes _sig)
    {
        require(isValidSigntureAndMethod(msg.sender, _sig));
        _;
    }
    //需要保鏢提供對某個特定參數表的函數的有效簽名
    modifier onlyValidSigntureAndData(bytes _sig)
    {
        require(isValidSigntureAndData(msg.sender, _sig));
        _;
    }
    //允許合約所有者添加保鏢
    function addBouncer(address _bouncer)
         onlyOwner
         public
     {
         require(_bouncer != address(0));
         addRole(_bouncer, ROLE_BOUNCER);
     }    
     //允許合約所有者移除保鏢
     function removeBouncer(address _bouncer)
         onlyOwner
         public
     {
         require(_bouncer != address(0));
         removeRole(_bouncer, ROLE_BOUNCER);
     }    
     //判斷保鏢簽名是否是"this+sender"的簽名
     function isValidSignature(address _address, bytes _sig)
          internal
          view
          returns(bool)
     {
         return isValidDataHash(
             keccak256(abi.encodePacked(address(this), _address)),
             _sig
         );
     }
     //判斷保鏢簽名是否是"this+sender+methodId"的簽名
      function isValidSignatureAndMethod(address _address, bytes _sig)
          internal
          view
          returns(bool)
     {
         bytes memory data = new bytes (METHOD_ID_SIZE);
         for (uint i = 0; i < data.length; i++){
             data[i] = msg.data[];
         }
         return isValidDataHash(
             keccak256(abi.encodePacked(address(this), _address data)),
             _sig
         );
     }         
       //判斷保鏢簽名是否是"this+sender+methodId+params(s)"的簽名   
      function isValidSignatureAndData(address _address, bytes _sig)
          internal
          view
          returns(bool)
     {
         reqire(msg.data.length > SIGNATURE_SIZE);
         bytes memory data = new bytes (msg.data.length - SIGNATURE_SIZE);
         for (uint i = 0; i < data.length; i++){
             data[i] = msg.data[];
         }
         return isValidDataHash(
             keccak256(abi.encodePacked(address(this), _address data)),
             _sig
         );
     } 
     //一個internal函數酷誓,將hash值轉換成客戶端簽發(fā)的消息數據披坏,而后恢復成簽名公鑰來驗證簽名是否來自一個具有保鏢角色的地址。      function isValidDataHash(byte32 hash, bytes _sig)
          internal
          view
          returns(bool)
     {
         address signer = hash
             .toEthSignedMessageHash()
             .recover(_sig);
         return hasRole(signer, ROLE_BOUNCER);
     }            
}
這個合約繼承了Owner和RBAC盐数,它有一個所有者棒拂,且有一個保存了角色和相應地址的映射

 

白名單(Whitelist.sol)

pragma solidity ^0.4.24;

import "../Ownership/Ownable.sol";
import "../Ownership/rbac/RBAC.sol";

contract Whitelist is Ownable, RBAC{
    string public constant ROLE_WHITELISTED = "whitelist";
    modifier onlyIfWhitelisted(address _operator){
        checkRole(_operator, ROLE_WHITRLISTED);
        _;
    }
    //向白名單中添加一個地址
    function addAddressToWhitelist(address _operator)
        onlyOwner
        public
{
        addRole(_operator, ROLE_WHITELISTED); 
    }
    //檢查白名單中是否存在這個地址
    function whitelist(address _operator)
        onlyOwner
        public
        returns(bool)
{
        return hasRole(_operator, ROLE_WHITELISTED); 
    }
    //添加一組地址
    function addAddressesToWhitelist(address[] _operator)
        onlyOwner
        public
{
        for (uint256 i = 0; i < _operator.length; i++){
            addAddressToWhitelist(_operator[i]);
        }
    }         
    //從白名單中移除一個地址
    function removeAddressFromWhitelist(address _operator)
        onlyOwner
        public
{
        removeRole(_operator, ROLE_WHITELISTED); 
    } 
    //從白名單中移除一組地址
        function removeAddressesFromWhitelist(address[] _operator)
        onlyOwner
        public
{
        for (uint256 i = 0; i < _operator.length; i++){
            removeAddressFromWhitelist(_operator[i]);
        }
    }              
}

可自毀(Destructible.sol)

pragma solidity ^0.4.24;

import "../Ownership/Ownable.sol";

contract Destructible is Ownable{
    constructor() public payable{}
    //銷毀合約將余額發(fā)個合約所有者
    function destroy() onlyOwner public{
        selfdestruct(owner);
    }
    //銷毀合約將余額發(fā)個指定地址
    function destoryAndSend(address _recipient) onlyOwner public{
        selfdestruct(_recipient);
    }
}

可暫停運作(Pausable.sol)

pragma solidity ^0.4.24;

import "../Ownership/Ownable.sol";

contract Pausable is Ownable{
    event Pause();
    event Unpause();
    
    bool public paused = false;
    //在未暫停狀態(tài)下使用
    modifier whenNotPaused(){
        require(!paused);
        _;
    }
    //在暫停狀態(tài)下使用
    modifier whenPaused(){
        require(paused);
        _;
    }
    //合約所有者暫停合約
    function pause() onlyOwner wenNotPaused public {
        paused = true;
        emit pause();
    }
    //合約所有者啟動合約
     function Unpause() onlyOwner wenPaused public {
        paused = false;
        emit Unpause();
    }
}

token可自毀(TokenDestuctible.sol)

pragma solidity ^0.4.24;

import "../Ownership/Ownable.sol";
import "../token/ERC20/ERC20Gasic.sol";

contract TokenDestuctible is Ownable{
    constructor() public payable{}
    
    function destroy(address[] tokens) onlyOwner public{
        for (uint256 i = 0; i < tokens.length; i++){
            ERC20Gasic token = ERC20Gasic(tokens[i]);
            uint256 balance = token.balanceOf(this);
            token.transfer(owner,balance);
        }
        selfdestruct(owner);//自毀
    }
}

托管(Escrow.sol)

pragma solidity ^0.4.24;

import "../Ownership/Ownable.sol";
import "../math/SafeMath";

contract Escrow is Ownable{
    using SafeMath for uint256;
    
    event Deposited(address indexed payee, uint256 weiAmount);
   event withdrawn(address indexed payee, uint256 weiAmount);
   
   mapping(address => uint256) private deposits;
   
   function depositsOf(address _payee) public view returns (uint256){
       renturn deposits[_payee];
   }
   //充值
   function deposit(address _payee) public onlyOwner payable{
       uint256 amount = msg.value;
       deposits[_payee] = deposits[_payee].add(amount);
       
       emit Deposited(_payee, amount);
   }
   //取回
   function withdraw(address _payee) public onlyOwner {
       uint256 payment = deposits[_payee];
       
       assert(address(this).balance >= payment);
       
       deposits[_payee] = 0;
       
       _payee.transfer(payment);
       
       emit Witndrawn(_payee, payment)
   }
}

條件托(ConditionalEscrow.sol)

super is 調用父類的回撤方法

pragma solidity ^0.4.24;

import "./Escrow.sol";

contract ConditionalEscrow is Escrow {
    function withdrawalAllowed(address _payee) public view returns(bool);
    
    function withdraw(address _payee) public{
        reqire(withdrawalAllowed(_payee));
       super.withdraw(_payee); 
    }
}

退還托管(RefundEscrow.sol)

pragma solidity ^0.4.24;

import "../Ownership/Ownable.sol";
import "./ConditionalEscrow.sol";

contract RefundEscrow is Ownable, ConditionalEscrow{
   enum State {Active, Refund, Closec}
   
    event Closed();
   event RefundsEnable();
        
    State public state;
    address public beneficiary;
    //_beneficiary受益人地址
    constructor(address _beneficiary) public {
        require(_beneficiary != address(0));
        beneficiary = _beneficiary;
        state = State.Active;//合約狀態(tài)
    }
    //為可能退還的處理保存資金
    function deposit(address _refundee) public paypable{
        require(state == State.Active);
        super.deposit(_refundee);
    }
    //允許受益人取回資金并拒絕其再次充值
    function colse() public onlyOwner{
        require(state == State.Active);
        state = State.Closed;
        emit Closed;
    }
    //允許款項退還拒絕其再次充值
    function enableRefunds() public onlyOwner{
        require(state == State.Active);
        state = State.Refunding;
        emit RefundsEnabled();
    }
    //將合約余額轉給受益人
    function beneficiaryWithdraw() public{
        require(state == State.Closed);
        beneficiary.transfer(address(this).balance);
    }                              
    //返回(是否正在進行退款處理)
    function withdrawalAllowed(address _payee) public view returns (bool){
        return state == State.Refunding;
    }                                                                                                                                                                  
}
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子帚屉,更是在濱河造成了極大的恐慌谜诫,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件攻旦,死亡現場離奇詭異喻旷,居然都是意外死亡,警方通過查閱死者的電腦和手機牢屋,發(fā)現死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進店門且预,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人伟阔,你說我怎么就攤上這事辣之。” “怎么了皱炉?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵怀估,是天一觀的道長。 經常有香客問我合搅,道長多搀,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任灾部,我火速辦了婚禮康铭,結果婚禮上,老公的妹妹穿的比我還像新娘赌髓。我一直安慰自己从藤,他們只是感情好,可當我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布锁蠕。 她就那樣靜靜地躺著夷野,像睡著了一般。 火紅的嫁衣襯著肌膚如雪荣倾。 梳的紋絲不亂的頭發(fā)上悯搔,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天,我揣著相機與錄音舌仍,去河邊找鬼妒貌。 笑死,一個胖子當著我的面吹牛铸豁,可吹牛的內容都是我干的灌曙。 我是一名探鬼主播,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼推姻,長吁一口氣:“原來是場噩夢啊……” “哼平匈!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤增炭,失蹤者是張志新(化名)和其女友劉穎忍燥,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體隙姿,經...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡梅垄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了输玷。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片队丝。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖欲鹏,靈堂內的尸體忽然破棺而出机久,到底是詐尸還是另有隱情,我是刑警寧澤赔嚎,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布膘盖,位于F島的核電站,受9級特大地震影響尤误,放射性物質發(fā)生泄漏侠畔。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一损晤、第九天 我趴在偏房一處隱蔽的房頂上張望软棺。 院中可真熱鬧,春花似錦尤勋、人聲如沸喘落。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽揖盘。三九已至,卻和暖如春锌奴,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背憾股。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工鹿蜀, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人服球。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓茴恰,卻偏偏與公主長得像,于是被迫代替她去往敵國和親斩熊。 傳聞我的和親對象是個殘疾皇子往枣,可洞房花燭夜當晚...
    茶點故事閱讀 43,465評論 2 348

推薦閱讀更多精彩內容