Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
O
openzeppelin-contracts-upgradeable
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
俞永鹏
openzeppelin-contracts-upgradeable
Commits
4fe2157e
Commit
4fe2157e
authored
Nov 23, 2017
by
zava
Committed by
Alejandro Santander
Jan 18, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Inheritable contract
parent
0cdc5e13
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
232 additions
and
0 deletions
+232
-0
Inheritable.sol
contracts/ownership/Inheritable.sol
+92
-0
Inheritable.js
test/Inheritable.js
+140
-0
No files found.
contracts/ownership/Inheritable.sol
0 → 100644
View file @
4fe2157e
pragma solidity ^0.4.11;
import './Ownable.sol';
/**
* @title Inheritable
* @dev The Inheritable contract provides ownership transfer capabilities, in the
* case that the current owner stops "heartbeating". Only the heir can pronounce the
* owner's death.
*/
contract Inheritable2 is Ownable {
address public heir;
// Time window the owner has to notify she is alive.
uint public heartbeatTimeout;
// Timestamp of the owner's death, as pronounced by the heir.
uint public timeOfDeath;
event OwnerPronouncedDead(address indexed owner, address indexed heir, uint indexed timeOfDeath);
/**
* @dev Throw an exception if called by any account other than the heir's.
*/
modifier onlyHeir() {
require(msg.sender == heir);
_;
}
/**
* @notice Create a new Inheritable Contract with heir address 0x0.
* @param _heartbeatTimeout time available for the owner to notify she's alive,
* before the heir can take ownership.
*/
function Inheritable(uint _heartbeatTimeout) public {
heartbeatTimeout = _heartbeatTimeout;
}
function setHeir(address newHeir) public onlyOwner {
heir = newHeir;
}
/**
* @dev set heir = 0x0
*/
function removeHeir() public onlyOwner {
delete(heir);
}
function setHeartbeatTimeout(uint newHeartbeatTimeout) public onlyOwner {
require(ownerLives());
heartbeatTimeout = newHeartbeatTimeout;
}
/**
* @dev Heir can pronounce the owners death. To inherit the ownership, he will
* have to wait for `heartbeatTimeout` seconds.
*/
function pronounceDeath() public onlyHeir {
require(ownerLives());
timeOfDeath = now;
OwnerPronouncedDead(owner, heir, timeOfDeath);
}
/**
* @dev Owner can send a heartbeat if she was mistakenly pronounced dead.
*/
function heartbeat() public onlyOwner {
delete(timeOfDeath);
}
/**
* @dev Allows heir to transfer ownership only if heartbeat has timed out.
*/
function inherit() public onlyHeir {
require(!ownerLives());
require(now >= timeOfDeath + heartbeatTimeout);
OwnershipTransferred(owner, heir);
owner = heir;
delete(timeOfDeath);
}
function ownerLives() internal returns (bool) {
return timeOfDeath == 0;
}
}
\ No newline at end of file
test/Inheritable.js
0 → 100644
View file @
4fe2157e
'use strict'
import
{
advanceBlock
}
from
'./helpers/advanceToBlock'
import
increaseTime
from
'./helpers/increaseTime'
import
{
increaseTimeTo
,
duration
}
from
'./helpers/increaseTime'
import
assertJump
from
'./helpers/assertJump'
const
NULL_ADDRESS
=
'0x0000000000000000000000000000000000000000'
const
Inheritable
=
artifacts
.
require
(
'../contracts/ownership/Inheritable2.sol'
)
contract
(
'Inheritable'
,
function
(
accounts
)
{
let
inheritable
let
owner
beforeEach
(
async
function
()
{
inheritable
=
await
Inheritable
.
new
()
owner
=
await
inheritable
.
owner
()
})
it
(
'should start off with an owner, but without heir'
,
async
function
()
{
const
heir
=
await
inheritable
.
heir
()
assert
.
equal
(
typeof
(
owner
),
'string'
)
assert
.
equal
(
typeof
(
heir
),
'string'
)
assert
.
notStrictEqual
(
owner
,
NULL_ADDRESS
,
"Owner shouldn't be the null address"
)
assert
.
isTrue
(
heir
===
NULL_ADDRESS
,
"Heir should be the null address"
)
})
it
(
'only owner should set heir'
,
async
function
()
{
const
newHeir
=
accounts
[
1
]
const
someRandomAddress
=
accounts
[
2
]
assert
.
isTrue
(
owner
!==
someRandomAddress
)
await
inheritable
.
setHeir
(
newHeir
,
{
from
:
owner
})
try
{
await
inheritable
.
setHeir
(
newHeir
,
{
from
:
someRandomAddress
})
assert
.
fail
(
'should have thrown before'
)
}
catch
(
error
)
{
assertJump
(
error
)
}
})
it
(
'owner can remove heir'
,
async
function
()
{
const
newHeir
=
accounts
[
1
]
await
inheritable
.
setHeir
(
newHeir
,
{
from
:
owner
})
let
heir
=
await
inheritable
.
heir
()
assert
.
notStrictEqual
(
heir
,
NULL_ADDRESS
)
await
inheritable
.
removeHeir
()
heir
=
await
inheritable
.
heir
()
assert
.
isTrue
(
heir
===
NULL_ADDRESS
)
})
it
(
'owner can set heartbeatTimeout only if she
\'
s alive'
,
async
function
()
{
const
newTimeout
=
41414141
await
inheritable
.
setHeartbeatTimeout
(
newTimeout
,
{
from
:
owner
})
assert
.
isTrue
((
await
inheritable
.
heartbeatTimeout
()).
equals
(
new
web3
.
BigNumber
(
newTimeout
)))
const
heir
=
accounts
[
1
]
await
inheritable
.
setHeir
(
heir
,
{
from
:
owner
})
await
inheritable
.
pronounceDeath
({
from
:
heir
})
try
{
await
inheritable
.
setHeartbeatTimeout
(
newTimeout
,
{
from
:
owner
})
assert
.
fail
(
'should have thrown before'
)
}
catch
(
error
)
{
assertJump
(
error
)
}
})
it
(
'heir can inherit only if owner is dead and timeout was reached'
,
async
function
()
{
const
heir
=
accounts
[
1
]
await
inheritable
.
setHeir
(
heir
,
{
from
:
owner
})
await
inheritable
.
setHeartbeatTimeout
(
4141
,
{
from
:
owner
})
try
{
await
inheritable
.
inherit
({
from
:
heir
})
assert
.
fail
(
'should have thrown before'
)
}
catch
(
error
)
{
assertJump
(
error
)
}
await
inheritable
.
pronounceDeath
({
from
:
heir
})
await
increaseTime
(
1
)
try
{
await
inheritable
.
inherit
({
from
:
heir
})
assert
.
fail
(
'should have thrown before'
)
}
catch
(
error
)
{
assertJump
(
error
)
}
await
increaseTime
(
4141
)
await
inheritable
.
inherit
({
from
:
heir
})
})
it
(
'heir can
\'
t inherit if owner heartbeats'
,
async
function
()
{
const
heir
=
accounts
[
1
]
await
inheritable
.
setHeir
(
heir
,
{
from
:
owner
})
await
inheritable
.
setHeartbeatTimeout
(
4141
,
{
from
:
owner
})
await
inheritable
.
pronounceDeath
({
from
:
heir
})
await
inheritable
.
heartbeat
({
from
:
owner
})
try
{
await
inheritable
.
inherit
({
from
:
heir
})
assert
.
fail
(
'should have thrown before'
)
}
catch
(
error
)
{
assertJump
(
error
)
}
await
inheritable
.
pronounceDeath
({
from
:
heir
})
await
increaseTime
(
4141
)
await
inheritable
.
heartbeat
({
from
:
owner
})
try
{
await
inheritable
.
inherit
({
from
:
heir
})
assert
.
fail
(
'should have thrown before'
)
}
catch
(
error
)
{
assertJump
(
error
)
}
})
it
(
'should log owner dead and ownership transfer'
,
async
function
()
{
const
heir
=
accounts
[
1
]
await
inheritable
.
setHeir
(
heir
,
{
from
:
owner
})
const
{
logs
}
=
await
inheritable
.
pronounceDeath
({
from
:
heir
})
const
event
=
logs
.
find
(
e
=>
e
.
event
===
'OwnerPronouncedDead'
)
assert
.
isTrue
(
event
.
args
.
owner
===
owner
)
assert
.
isTrue
(
event
.
args
.
heir
===
heir
)
})
})
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment