Heritable.sol 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. pragma solidity ^0.4.11;
  2. import "./Ownable.sol";
  3. /**
  4. * @title Heritable
  5. * @dev The Heritable contract provides ownership transfer capabilities, in the
  6. * case that the current owner stops "heartbeating". Only the heir can pronounce the
  7. * owner's death.
  8. */
  9. contract Heritable is Ownable {
  10. address public heir;
  11. // Time window the owner has to notify they are alive.
  12. uint256 public heartbeatTimeout;
  13. // Timestamp of the owner's death, as pronounced by the heir.
  14. uint256 public timeOfDeath;
  15. event HeirChanged(address indexed owner, address indexed newHeir);
  16. event OwnerHeartbeated(address indexed owner);
  17. event OwnerProclaimedDead(address indexed owner, address indexed heir, uint256 timeOfDeath);
  18. event HeirOwnershipClaimed(address indexed previousOwner, address indexed newOwner);
  19. /**
  20. * @dev Throw an exception if called by any account other than the heir's.
  21. */
  22. modifier onlyHeir() {
  23. require(msg.sender == heir);
  24. _;
  25. }
  26. /**
  27. * @notice Create a new Heritable Contract with heir address 0x0.
  28. * @param _heartbeatTimeout time available for the owner to notify they are alive,
  29. * before the heir can take ownership.
  30. */
  31. function Heritable(uint256 _heartbeatTimeout) public {
  32. setHeartbeatTimeout(_heartbeatTimeout);
  33. }
  34. function setHeir(address newHeir) public onlyOwner {
  35. require(newHeir != owner);
  36. heartbeat();
  37. HeirChanged(owner, newHeir);
  38. heir = newHeir;
  39. }
  40. /**
  41. * @dev set heir = 0x0
  42. */
  43. function removeHeir() public onlyOwner {
  44. heartbeat();
  45. heir = 0;
  46. }
  47. /**
  48. * @dev Heir can pronounce the owners death. To claim the ownership, they will
  49. * have to wait for `heartbeatTimeout` seconds.
  50. */
  51. function proclaimDeath() public onlyHeir {
  52. require(ownerLives());
  53. OwnerProclaimedDead(owner, heir, timeOfDeath);
  54. timeOfDeath = now;
  55. }
  56. /**
  57. * @dev Owner can send a heartbeat if they were mistakenly pronounced dead.
  58. */
  59. function heartbeat() public onlyOwner {
  60. OwnerHeartbeated(owner);
  61. timeOfDeath = 0;
  62. }
  63. /**
  64. * @dev Allows heir to transfer ownership only if heartbeat has timed out.
  65. */
  66. function claimHeirOwnership() public onlyHeir {
  67. require(!ownerLives());
  68. require(now >= timeOfDeath + heartbeatTimeout);
  69. OwnershipTransferred(owner, heir);
  70. HeirOwnershipClaimed(owner, heir);
  71. owner = heir;
  72. timeOfDeath = 0;
  73. }
  74. function setHeartbeatTimeout(uint256 newHeartbeatTimeout) internal onlyOwner {
  75. require(ownerLives());
  76. heartbeatTimeout = newHeartbeatTimeout;
  77. }
  78. function ownerLives() internal view returns (bool) {
  79. return timeOfDeath == 0;
  80. }
  81. }