Commit d8d902ba authored by Simon de la Rouviere's avatar Simon de la Rouviere

Add HumanStandardToken.

parent f935704b
......@@ -17,11 +17,16 @@ var FactoryPage = React.createClass({
<TXComponent filter={{txType: "token_creation"}}>
<TxForm txType = "token_creation"
header = "Create Token"
msg = "Create Token Contract with the following initial amount."
msg = "Create Token Contract with the following parameters."
buttonAction = "Create Token"
buttonProcessing = "Creating Token"
successful = {this.successOnCreation}
inputs = {[{placeholder: "amount: eg. 10", key: "amount", ref: "amount"}]}
inputs = {[{placeholder: "totaly supply: eg. 10", key: "amount", ref: "amount"},
{placeholder: "name: eg Simon Bucks", key: "name", ref: "name"},
{placeholder: "decimal places: eg 4", key: "decimals", ref: "decimals"},
{placeholder: "symbol: eg SBX", key: "symbol", ref: "symbol"},
]}
/>
</TXComponent> <br />
</div>
......
......@@ -101,8 +101,7 @@ window.onload = function() {
// check if RPC is online. Why though?
//web3.eth.getCoinbase(function(error, coinbase) {
//window.MainRouter = Router;
Standard_Token.load(Pudding);
//console.log(Standard_Token.prototype.binary);
HumanStandardToken.load(Pudding);
ReactDOM.render((
//React.render((
......
......@@ -14,21 +14,33 @@ var TokenPage = React.createClass({
transferFrom_result: '',
approve_result: '',
allowance_result: '',
token_decimals: '',
token_name: '',
token_symbol: ''
};
},
componentDidMount: function() {
this.setState({contract_address: this.props.params.contract_address});
//var web3_token = web3_rab.eth.contract(Standard_Token.abi).at(this.props.params.contract_address); //for reflux-tx
var web3_token = web3.eth.contract(Standard_Token.abi).at(this.props.params.contract_address); //for reflux-tx
//var web3_token = web3_rab.eth.contract(HumanStandardToken.abi).at(this.props.params.contract_address); //for reflux-tx
var web3_token = web3.eth.contract(HumanStandardToken.abi).at(this.props.params.contract_address); //for reflux-tx
window.token_c = web3_token;
this.setState({web3_token: web3_token});
var that = this;
web3.eth.getAccounts(function(err, accounts){
var addr = accounts[0];
console.log(addr);
var totalSupply = web3_token.totalSupply.call({from: addr});
console.log(totalSupply);
that.setState({totalSupply: totalSupply.c[0]});
that.setState({current_user_address: addr});
var decimals = web3_token.decimals.call({from: addr});
var symbol = web3_token.symbol.call({from: addr});
var name = web3_token.name.call({from: addr});
if(decimals) { that.setState({token_decimals: decimals}); }
if(symbol) { that.setState({token_symbol: symbol}); }
if(name) { that.setState({token_name: name}); }
console.log(decimals + symbol + name);
});
},
successOnBalance: function(result, args) {
......@@ -77,11 +89,20 @@ var TokenPage = React.createClass({
},
render: function() {
//return error if not actual token system.
var transfer_header = '';
if(this.state.token_name != '') { transfer_header = "Transfer " + this.state.token_name; } else { transfer_header = "Transfer Token"; }
var top_header = '';
if(this.state.token_symbol != '') {
top_header = <span><h2>{this.state.token_name} ({this.state.token_symbol})</h2> <br /></span>;
}
//Current User Address & Balance: {this.state.current_user_address}. <br />
return (
<div>
{top_header}
Interacting with token at address: {this.state.contract_address}. <br />
Total Supply is: {this.state.totalSupply}. <br />
Current User Address & Balance: {this.state.current_user_address}. <br />
<br />
<div className="form-group">
<TXComponent filter={{txType: "transfer"}}>
......@@ -89,7 +110,7 @@ var TokenPage = React.createClass({
txStyle = "transaction"
txType = "transfer"
abiFunction = "transfer"
header = "Transfer Token"
header = {transfer_header}
msg = "Transfer to another account."
buttonAction = "Transfer Amount"
buttonProcessing = "Transferring Amount"
......
......@@ -67,22 +67,26 @@ var TxForm = React.createClass({
if(typeof this.props.web3_token == 'undefined') {
//token creation execution
console.log('creating');
var ST = web3.eth.contract(Standard_Token.abi);
var ST = web3.eth.contract(HumanStandardToken.abi);
var tx_hash = null;
var that = this;
//var creation_data = ST.new.getData(args[0], {data: Standard_Token.binary});
//var creation_data = ST.new.getData(args[0], {data: HumanStandardToken.binary});
console.log(web3);
web3.eth.getAccounts(function(err, accounts){
var addr = accounts[0];
console.log(addr);
console.log(ST);
console.log(Standard_Token.abi);
console.log("0x"+Standard_Token.prototype.binary);
console.log(HumanStandardToken.abi);
console.log("0x"+HumanStandardToken.prototype.binary);
//TODO: change gas price
var creation_data = ST.new.getData(args[0], {from: addr, data: "0x" + Standard_Token.prototype.binary, gasPrice: 50000000000, gas: 3100000});
//args[0] = uint256 _initialAmount,
//args[1] = string _tokenName,
//args[2] = uint8 _decimalUnits,
//args[3] = string _tokenSymbol
var creation_data = ST.new.getData(args[0], args[1], args[2], args[3], {from: addr, data: "0x" + HumanStandardToken.prototype.binary, gasPrice: 50000000000, gas: 3100000});
console.log(creation_data);
console.log(args[0]);
ST.new(args[0], {from: addr, data: "0x" + Standard_Token.prototype.binary, gasPrice: 50000000000, gas: 1000000}, function(err, result) {
ST.new(args[0], args[1], args[2], args[3], {from: addr, data: "0x" + HumanStandardToken.prototype.binary, gasPrice: 50000000000, gas: 1000000}, function(err, result) {
//NOTE: This callback fires twice. Once tx hash comes in. Then when mined.
if(err) {
console.log(err);
......
......@@ -12,8 +12,8 @@ if (typeof web3 !== 'undefined') {
exported = new Web3(web3.currentProvider);
window.offline = false; //there is a web3 available.
//var other_web3 = new Web3(new Web3.providers.HttpProvider('http://127.0.0.1:8545'));
//window.web_l = other_web3;
var other_web3 = new Web3(new Web3.providers.HttpProvider('https://rpc.metamask.io'));
window.web_l = other_web3;
} else {
// Use the provider from the config.
// ENV and WEB3_PROVIDER_LOCATION are rewritten by webpack during build
......
/*
This Token Contract implements the standard token functionality (https://github.com/ethereum/EIPs/issues/20) as well as the following OPTIONAL extras intended for use by humans.
In other words. This is intended for deployment in something like a Token Factory or Mist wallet, and then used by humans.
Imagine coins, currencies, shares, voting weight, etc.
Machine-based, rapid creation of many tokens would not necessarily need these extra features or will be minted in other manners.
1) Initial Finite Supply (upon creation one specifies how much is minted).
2) In the absence of a token registry: Optional Decimal, Symbol & Name.
3) Optional approveAndCall() functionality to notify a contract if an approval() has occurred.
.*/
import "StandardToken.sol";
contract HumanStandardToken is StandardToken {
function () {
//if ether is sent to this address, send it back.
throw;
}
/* Public variables of the token */
/*
NOTE:
The following variables are OPTIONAL vanities. One does not have to include them.
They allow one to customise the token contract & in no way influences the core functionality.
Some wallets/interfaces might not even bother to look at this information.
*/
string public name; //fancy name: eg Simon Bucks
uint8 public decimals; //How many decimals to show. ie. There could 1000 base units with 3 decimals. Meaning 0.980 SBX = 980 base units. It's like comparing 1 wei to 1 ether.
string public symbol; //An identifier: eg SBX
string public version = 'H0.1'; //human 0.1 standard. Just an arbitrary versioning scheme.
function HumanStandardToken(
uint256 _initialAmount,
string _tokenName,
uint8 _decimalUnits,
string _tokenSymbol
) {
balances[msg.sender] = _initialAmount; // Give the creator all initial tokens
totalSupply = _initialAmount; // Update total supply
name = _tokenName; // Set the name for display purposes
decimals = _decimalUnits; // Amount of decimals for display purposes
symbol = _tokenSymbol; // Set the symbol for display purposes
}
/* Approves and then calls the receiving contract */
function approveAndCall(address _spender, uint256 _value, bytes _extraData) returns (bool success) {
allowed[msg.sender][_spender] = _value;
//call the receiveApproval function on the contract you want to be notified. This crafts the function signature manually so one doesn't have to include a contract in here just for this.
//receiveApproval(address _from, uint256 _value, address _tokenContract, bytes _extraData)
_spender.call(bytes4(bytes32(sha3("receiveApproval(address,uint256,address,bytes)"))), msg.sender, _value, this, _extraData);
Approval(msg.sender, _spender, _value);
return true;
}
}
/*Most, basic default, standardised Token contract.
Allows the creation of a token with a finite issued amount to the creator.
/*
This implements ONLY the standard functions and NOTHING else.
For a token like you would want to deploy in something like Mist, see HumanStandardToken.sol.
Based on standardised APIs: https://github.com/ethereum/wiki/wiki/Standardized_Contract_APIs
If you deploy this, you won't have anything useful.
Implements ERC 20 Token standard: https://github.com/ethereum/EIPs/issues/20
.*/
import "Token.sol";
contract Standard_Token is Token {
function Standard_Token(uint256 _initial_amount) {
balances[msg.sender] = _initial_amount;
total_supply = _initial_amount;
}
contract StandardToken is Token {
function transfer(address _to, uint256 _value) returns (bool success) {
//Default assumes totalSupply can't be over max (2^256 - 1).
......@@ -26,17 +24,14 @@ contract Standard_Token is Token {
} else { return false; }
}
//NOTE: This function suffers from a bug atm. It is a hack. It only works if the calls are arranged as is below.
//Here be dragons. Not sure if VM or Solidity bug. More testing needs to be done.
//See: https://github.com/ethereum/solidity/issues/281
function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
//same as above. Replace this line with the following if you want to protect against wrapping uints.
//if (balances[_from] >= _value && allowed[_from][msg.sender] >= _value && balances[_to] + _value > balances[_to]) {
if (balances[_from] >= _value && allowed[_from][msg.sender] >= _value && _value > 0) {
balances[_to] += _value;
Transfer(_from, _to, _value);
balances[_from] -= _value;
allowed[_from][msg.sender] -= _value;
Transfer(_from, _to, _value);
return true;
} else { return false; }
}
......@@ -55,11 +50,7 @@ contract Standard_Token is Token {
return allowed[_owner][_spender];
}
function totalSupply() constant returns (uint256 _total) {
return total_supply;
}
mapping (address => uint256) balances;
mapping (address => mapping (address => uint256)) allowed;
uint256 total_supply;
uint256 public totalSupply;
}
import "Standard_Token.sol";
contract Standard_Token_Factory {
mapping(address => address[]) public created;
function createdByMe() returns (address[]) {
return created[msg.sender];
}
function createStandardToken(uint256 _initialAmount) returns (address) {
address newTokenAddr = address(new Standard_Token(_initialAmount));
Standard_Token newToken = Standard_Token(newTokenAddr);
newToken.transfer(msg.sender, _initialAmount); //the factory will own the created tokens. You must transfer them.
created[msg.sender].push(newTokenAddr);
return newTokenAddr;
}
}
contract Token {
/// @return total amount of tokens
function totalSupply() constant returns (uint256 supply) {}
/// @param _owner The address from which the balance will be retrieved
/// @return The balance
function balanceOf(address _owner) constant returns (uint256 balance) {}
/// @notice send `_value` token to `_to` from `msg.sender`
/// @param _to The address of the recipient
/// @param _value The amount of token to be transferred
/// @return Whether the transfer was successful or not
function transfer(address _to, uint256 _value) returns (bool success) {}
/// @notice send `_value` token to `_to` from `_from` on the condition it is approved by `_from`
/// @param _from The address of the sender
/// @param _to The address of the recipient
/// @param _value The amount of token to be transferred
/// @return Whether the transfer was successful or not
function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {}
/// @notice `msg.sender` approves `_addr` to spend `_value` tokens
/// @param _spender The address of the account able to transfer the tokens
/// @param _value The amount of wei to be approved for transfer
/// @return Whether the approval was successful or not
function approve(address _spender, uint256 _value) returns (bool success) {}
/// @param _owner The address of the account owning tokens
/// @param _spender The address of the account able to transfer the tokens
/// @return Amount of remaining tokens allowed to spent
function allowance(address _owner, address _spender) constant returns (uint256 remaining) {}
event Transfer(address indexed _from, address indexed _to, uint256 _value);
......
This diff is collapsed.
// Factory "morphs" into a Pudding class.
// The reasoning is that calling load in each context
// is cumbersome.
(function() {
var contract_data = {
abi: [{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"remaining","type":"uint256"}],"type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_owner","type":"address"},{"indexed":true,"name":"_spender","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Approval","type":"event"}],
binary: "6060604052610321806100126000396000f3606060405236156100565760e060020a6000350463095ea7b3811461005857806318160ddd146100c357806323b872dd146100cc57806370a0823114610230578063a9059cbb14610256578063dd62ed3e146102e8575b005b61024c60043560243533600160a060020a03908116600081815260016020908152604080832094871680845294825282208590556060858152919392917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259190a35060015b92915050565b61024c60025481565b61024c600435602435604435600160a060020a03831660009081526020819052604081205482901080159061011f575060016020908152604080832033600160a060020a03168452909152812054829010155b801561012b5750600082115b1561022957816000600050600085600160a060020a03168152602001908152602001600020600082828250540192505081905550816000600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816001600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a0316815260200190815260200160002060008282825054039250508190555082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a35060015b9392505050565b600160a060020a03600435166000908152602081905260409020545b6060908152602090f35b61024c60043560243533600160a060020a03166000908152602081905260408120548290108015906102885750600082115b1561031c57604080822080548490039055600160a060020a03808516808452918320805485019055606084815233909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602090a35060016100bd565b61024c600435602435600160a060020a038083166000908152600160209081526040808320938516835292905220546100bd565b6100bd56",
unlinked_binary: "6060604052610321806100126000396000f3606060405236156100565760e060020a6000350463095ea7b3811461005857806318160ddd146100c357806323b872dd146100cc57806370a0823114610230578063a9059cbb14610256578063dd62ed3e146102e8575b005b61024c60043560243533600160a060020a03908116600081815260016020908152604080832094871680845294825282208590556060858152919392917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259190a35060015b92915050565b61024c60025481565b61024c600435602435604435600160a060020a03831660009081526020819052604081205482901080159061011f575060016020908152604080832033600160a060020a03168452909152812054829010155b801561012b5750600082115b1561022957816000600050600085600160a060020a03168152602001908152602001600020600082828250540192505081905550816000600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816001600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a0316815260200190815260200160002060008282825054039250508190555082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a35060015b9392505050565b600160a060020a03600435166000908152602081905260409020545b6060908152602090f35b61024c60043560243533600160a060020a03166000908152602081905260408120548290108015906102885750600082115b1561031c57604080822080548490039055600160a060020a03808516808452918320805485019055606084815233909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602090a35060016100bd565b61024c600435602435600160a060020a038083166000908152600160209081526040808320938516835292905220546100bd565b6100bd56",
address: "",
generated_with: "2.0.9",
contract_name: "StandardToken"
};
function Contract() {
if (Contract.Pudding == null) {
throw new Error("StandardToken error: Please call load() first before creating new instance of this contract.");
}
Contract.Pudding.apply(this, arguments);
};
Contract.load = function(Pudding) {
Contract.Pudding = Pudding;
Pudding.whisk(contract_data, Contract);
// Return itself for backwards compatibility.
return Contract;
}
Contract.new = function() {
if (Contract.Pudding == null) {
throw new Error("StandardToken error: Please call load() first before calling new().");
}
return Contract.Pudding.new.apply(Contract, arguments);
};
Contract.at = function() {
if (Contract.Pudding == null) {
throw new Error("StandardToken error: Please call load() first before calling at().");
}
return Contract.Pudding.at.apply(Contract, arguments);
};
Contract.deployed = function() {
if (Contract.Pudding == null) {
throw new Error("StandardToken error: Please call load() first before calling deployed().");
}
return Contract.Pudding.deployed.apply(Contract, arguments);
};
if (typeof module != "undefined" && typeof module.exports != "undefined") {
module.exports = Contract;
} else {
// There will only be one version of Pudding in the browser,
// and we can use that.
window.StandardToken = Contract;
}
})();
// Factory "morphs" into a Pudding class.
// The reasoning is that calling load in each context
// is cumbersome.
var contract_data = {
abi: [{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"_total","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"remaining","type":"uint256"}],"type":"function"},{"inputs":[{"name":"_initial_amount","type":"uint256"}],"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_owner","type":"address"},{"indexed":true,"name":"_spender","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Approval","type":"event"}],
binary: "6060604052604051602080610337833950608060405251600160a060020a03331660009081526020819052604090208190556002819055506102f2806100456000396000f3606060405236156100565760e060020a6000350463095ea7b3811461005857806318160ddd146100c357806323b872dd146100d157806370a0823114610207578063a9059cbb14610227578063dd62ed3e146102b9575b005b6100c760043560243533600160a060020a03908116600081815260016020908152604080832094871680845294825282208590556060858152919392917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259190a35060015b92915050565b6002545b6060908152602090f35b6100c7600435602435604435600160a060020a038316600090815260208190526040812054829010801590610124575060016020908152604080832033600160a060020a03168452909152812054829010155b80156101305750600082115b1561020057600160a060020a03808416808352602083815260408420805486019055606085815291928716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9190a3816000600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816001600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a03168152602001908152602001600020600082828250540392505081905550600190505b9392505050565b600160a060020a03600435166000908152602081905260409020546100c7565b6100c760043560243533600160a060020a03166000908152602081905260408120548290108015906102595750600082115b156102ed57604080822080548490039055600160a060020a03808516808452918320805485019055606084815233909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602090a35060016100bd565b6100c7600435602435600160a060020a038083166000908152600160209081526040808320938516835292905220546100bd565b6100bd56",
address: "",
generated_with: "2.0.2",
contract_name: "Standard_Token"
};
function Contract() {
if (Contract.Pudding == null) {
throw new Error("Standard_Token error: Please call load() first before creating new instance of this contract.");
}
Contract.Pudding.apply(this, arguments);
};
Contract.load = function(Pudding) {
Contract.Pudding = Pudding;
Pudding.whisk(contract_data, Contract);
// Return itself for backwards compatibility.
return Contract;
}
Contract.new = function() {
if (Contract.Pudding == null) {
throw new Error("Standard_Token error: Please call load() first before calling new().");
}
return Contract.Pudding.new.apply(Contract, arguments);
};
Contract.at = function() {
if (Contract.Pudding == null) {
throw new Error("Standard_Token error: lease call load() first before calling at().");
}
return Contract.Pudding.at.apply(Contract, arguments);
};
Contract.deployed = function() {
if (Contract.Pudding == null) {
throw new Error("Standard_Token error: Please call load() first before calling deployed().");
}
return Contract.Pudding.deployed.apply(Contract, arguments);
};
if (typeof module != "undefined" && typeof module.exports != "undefined") {
module.exports = Contract;
} else {
// There will only be one version of Pudding in the browser,
// and we can use that.
window.Standard_Token = Contract;
}
// Factory "morphs" into a Pudding class.
// The reasoning is that calling load in each context
// is cumbersome.
var contract_data = {
abi: [{"constant":false,"inputs":[{"name":"_initialAmount","type":"uint256"}],"name":"createStandardToken","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"uint256"}],"name":"created","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":false,"inputs":[],"name":"createdByMe","outputs":[{"name":"","type":"address[]"}],"type":"function"}],
binary: "6060604052610598806100126000396000f3606060405260e060020a600035046305215b2f81146100315780635f8dead314610107578063dc3f65d314610143575b005b6101bb600435600080808360606103378061026183390180828152602001915050604051809103906000f0915081905080600160a060020a031663a9059cbb33866040518360e060020a0281526004018083600160a060020a03168152602001828152602001925050506020604051808303816000876161da5a03f11561000257505050600160a060020a033316835260208390526040832080546001810180835582818380158290116102225781836000526020600020918201910161022291905b8082111561025d578a81556001016100f4565b6101bb60043560243560006020819052828152604090208054829081101561000257506000908152602090200154600160a060020a0316905081565b6101d860006060818152600160a060020a03331682526020828152604092839020805460a09281028301909452608084815292939091828280156101b157602002820191906000526020600020905b8154600160a060020a0316815260019190910190602001808311610192575b5050505050905090565b60408051600160a060020a03929092168252519081900360200190f35b60405180806020018281038252838181518152602001915080519060200190602002808383829060006004602084601f0104600f02600301f1509050019250505060405180910390f35b50505091909060005260206000209001600050805473ffffffffffffffffffffffffffffffffffffffff191683179055509150805050919050565b5090566060604052604051602080610337833950608060405251600160a060020a03331660009081526020819052604090208190556002819055506102f2806100456000396000f3606060405236156100565760e060020a6000350463095ea7b3811461005857806318160ddd146100c357806323b872dd146100d157806370a0823114610207578063a9059cbb14610227578063dd62ed3e146102b9575b005b6100c760043560243533600160a060020a03908116600081815260016020908152604080832094871680845294825282208590556060858152919392917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259190a35060015b92915050565b6002545b6060908152602090f35b6100c7600435602435604435600160a060020a038316600090815260208190526040812054829010801590610124575060016020908152604080832033600160a060020a03168452909152812054829010155b80156101305750600082115b1561020057600160a060020a03808416808352602083815260408420805486019055606085815291928716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9190a3816000600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816001600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a03168152602001908152602001600020600082828250540392505081905550600190505b9392505050565b600160a060020a03600435166000908152602081905260409020546100c7565b6100c760043560243533600160a060020a03166000908152602081905260408120548290108015906102595750600082115b156102ed57604080822080548490039055600160a060020a03808516808452918320805485019055606084815233909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602090a35060016100bd565b6100c7600435602435600160a060020a038083166000908152600160209081526040808320938516835292905220546100bd565b6100bd56",
address: "",
generated_with: "2.0.2",
contract_name: "Standard_Token_Factory"
};
function Contract() {
if (Contract.Pudding == null) {
throw new Error("Standard_Token_Factory error: Please call load() first before creating new instance of this contract.");
}
Contract.Pudding.apply(this, arguments);
};
Contract.load = function(Pudding) {
Contract.Pudding = Pudding;
Pudding.whisk(contract_data, Contract);
// Return itself for backwards compatibility.
return Contract;
}
Contract.new = function() {
if (Contract.Pudding == null) {
throw new Error("Standard_Token_Factory error: Please call load() first before calling new().");
}
return Contract.Pudding.new.apply(Contract, arguments);
};
Contract.at = function() {
if (Contract.Pudding == null) {
throw new Error("Standard_Token_Factory error: lease call load() first before calling at().");
}
return Contract.Pudding.at.apply(Contract, arguments);
};
Contract.deployed = function() {
if (Contract.Pudding == null) {
throw new Error("Standard_Token_Factory error: Please call load() first before calling deployed().");
}
return Contract.Pudding.deployed.apply(Contract, arguments);
};
if (typeof module != "undefined" && typeof module.exports != "undefined") {
module.exports = Contract;
} else {
// There will only be one version of Pudding in the browser,
// and we can use that.
window.Standard_Token_Factory = Contract;
}
......@@ -2,59 +2,64 @@
// The reasoning is that calling load in each context
// is cumbersome.
var contract_data = {
abi: [{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"supply","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"remaining","type":"uint256"}],"type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_owner","type":"address"},{"indexed":true,"name":"_spender","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Approval","type":"event"}],
binary: "6060604052605d8060106000396000f360606040523615604f5760e060020a6000350463095ea7b38114605157806318160ddd14605157806323b872dd14605157806370a08231146051578063a9059cbb146051578063dd62ed3e146051575b005b60006060908152602090f3",
address: "",
generated_with: "2.0.2",
contract_name: "Token"
};
function Contract() {
if (Contract.Pudding == null) {
throw new Error("Token error: Please call load() first before creating new instance of this contract.");
}
(function() {
var contract_data = {
abi: [{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"supply","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"remaining","type":"uint256"}],"type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_owner","type":"address"},{"indexed":true,"name":"_spender","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Approval","type":"event"}],
binary: "6060604052605d8060106000396000f360606040523615604f5760e060020a6000350463095ea7b38114605157806318160ddd14605157806323b872dd14605157806370a08231146051578063a9059cbb146051578063dd62ed3e146051575b005b60006060908152602090f3",
unlinked_binary: "6060604052605d8060106000396000f360606040523615604f5760e060020a6000350463095ea7b38114605157806318160ddd14605157806323b872dd14605157806370a08231146051578063a9059cbb146051578063dd62ed3e146051575b005b60006060908152602090f3",
address: "",
generated_with: "2.0.9",
contract_name: "Token"
};
Contract.Pudding.apply(this, arguments);
};
function Contract() {
if (Contract.Pudding == null) {
throw new Error("Token error: Please call load() first before creating new instance of this contract.");
}
Contract.load = function(Pudding) {
Contract.Pudding = Pudding;
Contract.Pudding.apply(this, arguments);
};
Pudding.whisk(contract_data, Contract);
Contract.load = function(Pudding) {
Contract.Pudding = Pudding;
// Return itself for backwards compatibility.
return Contract;
}
Pudding.whisk(contract_data, Contract);
Contract.new = function() {
if (Contract.Pudding == null) {
throw new Error("Token error: Please call load() first before calling new().");
// Return itself for backwards compatibility.
return Contract;
}
return Contract.Pudding.new.apply(Contract, arguments);
};
Contract.new = function() {
if (Contract.Pudding == null) {
throw new Error("Token error: Please call load() first before calling new().");
}
Contract.at = function() {
if (Contract.Pudding == null) {
throw new Error("Token error: lease call load() first before calling at().");
}
return Contract.Pudding.new.apply(Contract, arguments);
};
return Contract.Pudding.at.apply(Contract, arguments);
};
Contract.at = function() {
if (Contract.Pudding == null) {
throw new Error("Token error: Please call load() first before calling at().");
}
Contract.deployed = function() {
if (Contract.Pudding == null) {
throw new Error("Token error: Please call load() first before calling deployed().");
}
return Contract.Pudding.at.apply(Contract, arguments);
};
return Contract.Pudding.deployed.apply(Contract, arguments);
};
Contract.deployed = function() {
if (Contract.Pudding == null) {
throw new Error("Token error: Please call load() first before calling deployed().");
}
return Contract.Pudding.deployed.apply(Contract, arguments);
};
if (typeof module != "undefined" && typeof module.exports != "undefined") {
module.exports = Contract;
} else {
// There will only be one version of Pudding in the browser,
// and we can use that.
window.Token = Contract;
}
if (typeof module != "undefined" && typeof module.exports != "undefined") {
module.exports = Contract;
} else {
// There will only be one version of Pudding in the browser,
// and we can use that.
window.Token = Contract;
}
})();
contract("Standard_Token", function(accounts) {
/*CREATION*/
it("creation: should create an initial balance of 10000 for the creator", function(done) {
Standard_Token.new(10000, {from: accounts[0]}).then(function(ctr) {
return ctr.balanceOf.call(accounts[0]);
}).then(function (result) {
assert.strictEqual(result.c[0], 10000);
done();
}).catch(done);
});
it("creation: should succeed in creating over 2^256 - 1 (max) tokens", function(done) {
//2^256 - 1
Standard_Token.new('115792089237316195423570985008687907853269984665640564039457584007913129639935', {from: accounts[0]}).then(function(ctr) {
return ctr.totalSupply();
}).then(function (result) {
var match = result.equals('1.15792089237316195423570985008687907853269984665640564039457584007913129639935e+77');
assert.isTrue(match);
done();
}).catch(done);
});
/*TRANSERS*/
//normal transfers without approvals.
it("transfers: should transfer 10000 to accounts[1] with accounts[0] having 10000", function(done) {
var ctr;
Standard_Token.new(10000, {from: accounts[0]}).then(function(result) {
ctr = result;
return ctr.transfer(accounts[1], 10000, {from: accounts[0]});
}).then(function (result) {
return ctr.balanceOf.call(accounts[1]);
}).then(function (result) {
assert.strictEqual(result.c[0], 10000);
done();
}).catch(done);
});
it("transfers: should fail when trying to transfer 10001 to accounts[1] with accounts[0] having 10000", function(done) {
var ctr;
Standard_Token.new(10000, {from: accounts[0]}).then(function(result) {
ctr = result;
return ctr.transfer.call(accounts[1], 10001, {from: accounts[0]});
}).then(function (result) {
assert.isFalse(result);
done();
}).catch(done);
});
it("transfers: should fail when trying to transfer zero.", function(done) {
var ctr;
Standard_Token.new(10000, {from: accounts[0]}).then(function(result) {
ctr = result;
return ctr.transfer.call(accounts[1], 0, {from: accounts[0]});
}).then(function (result) {
assert.isFalse(result);
done();
}).catch(done);
});
//NOTE: testing uint256 wrapping is impossible in this standard token since you can't supply > 2^256 -1.
//todo: transfer max amounts.
/*APPROVALS*/
it("approvals: msg.sender should approve 100 to accounts[1]", function(done) {
var ctr = null;
Standard_Token.new(10000, {from: accounts[0]}).then(function(result) {
ctr = result;
return ctr.approve(accounts[1], 100, {from: accounts[0]});
}).then(function (result) {
return ctr.allowance.call(accounts[0], accounts[1]);
}).then(function (result) {
assert.strictEqual(result.c[0], 100);
done();
}).catch(done);
});
//bit overkill. But is for testing a bug
it("approvals: msg.sender approves accounts[1] of 100 & withdraws 20 once.", function(done) {
var ctr = null;
Standard_Token.new(10000, {from: accounts[0]}).then(function(result) {
ctr = result;
return ctr.balanceOf.call(accounts[0]);
}).then(function (result) {
assert.strictEqual(result.c[0], 10000);
return ctr.approve(accounts[1], 100, {from: accounts[0]});
}).then(function (result) {
return ctr.balanceOf.call(accounts[2]);
}).then(function (result) {
assert.strictEqual(result.c[0], 0);
return ctr.allowance.call(accounts[0], accounts[1]);
}).then(function (result) {
assert.strictEqual(result.c[0], 100);
return ctr.transferFrom.call(accounts[0], accounts[2], 20, {from: accounts[1]});
}).then(function (result) {
return ctr.transferFrom(accounts[0], accounts[2], 20, {from: accounts[1]});
}).then(function (result) {
return ctr.allowance.call(accounts[0], accounts[1]);
}).then(function (result) {
assert.strictEqual(result.c[0], 80);
return ctr.balanceOf.call(accounts[2]);
}).then(function (result) {
assert.strictEqual(result.c[0], 20);
return ctr.balanceOf.call(accounts[0]);
}).then(function (result) {
assert.strictEqual(result.c[0], 9980);
done();
}).catch(done);
});
//should approve 100 of msg.sender & withdraw 50, twice. (should succeed)
it("approvals: msg.sender approves accounts[1] of 100 & withdraws 20 twice.", function(done) {
var ctr = null;
Standard_Token.new(10000, {from: accounts[0]}).then(function(result) {
ctr = result;
return ctr.approve(accounts[1], 100, {from: accounts[0]});
}).then(function (result) {
return ctr.allowance.call(accounts[0], accounts[1]);
}).then(function (result) {
assert.strictEqual(result.c[0], 100);
return ctr.transferFrom(accounts[0], accounts[2], 20, {from: accounts[1]});
}).then(function (result) {
return ctr.allowance.call(accounts[0], accounts[1]);
}).then(function (result) {
assert.strictEqual(result.c[0], 80);
return ctr.balanceOf.call(accounts[2]);
}).then(function (result) {
assert.strictEqual(result.c[0], 20);
return ctr.balanceOf.call(accounts[0]);
}).then(function (result) {
assert.strictEqual(result.c[0], 9980);
//FIRST tx done.
//onto next.
return ctr.transferFrom(accounts[0], accounts[2], 20, {from: accounts[1]});
}).then(function (result) {
return ctr.allowance.call(accounts[0], accounts[1]);
}).then(function (result) {
assert.strictEqual(result.c[0], 60);
return ctr.balanceOf.call(accounts[2]);
}).then(function (result) {
assert.strictEqual(result.c[0], 40);
return ctr.balanceOf.call(accounts[0]);
}).then(function (result) {
assert.strictEqual(result.c[0], 9960);
done();
}).catch(done);
});
//should approve 100 of msg.sender & withdraw 50 & 60 (should fail).
it("approvals: msg.sender approves accounts[1] of 100 & withdraws 50 & 60 (2nd tx should fail)", function(done) {
var ctr = null;
Standard_Token.new(10000, {from: accounts[0]}).then(function(result) {
ctr = result;
return ctr.approve(accounts[1], 100, {from: accounts[0]});
}).then(function (result) {
return ctr.allowance.call(accounts[0], accounts[1]);
}).then(function (result) {
assert.strictEqual(result.c[0], 100);
return ctr.transferFrom(accounts[0], accounts[2], 50, {from: accounts[1]});
}).then(function (result) {
return ctr.allowance.call(accounts[0], accounts[1]);
}).then(function (result) {
assert.strictEqual(result.c[0], 50);
return ctr.balanceOf.call(accounts[2]);
}).then(function (result) {
assert.strictEqual(result.c[0], 50);
return ctr.balanceOf.call(accounts[0]);
}).then(function (result) {
assert.strictEqual(result.c[0], 9950);
//FIRST tx done.
//onto next.
return ctr.transferFrom.call(accounts[0], accounts[2], 60, {from: accounts[1]});
}).then(function (result) {
assert.isFalse(result);
done();
}).catch(done);
});
it("approvals: attempt withdrawal from acconut with no allowance (should fail)", function(done) {
var ctr = null;
Standard_Token.new(10000, {from: accounts[0]}).then(function(result) {
ctr = result;
return ctr.transferFrom.call(accounts[0], accounts[2], 60, {from: accounts[1]});
}).then(function (result) {
assert.isFalse(result);
done();
}).catch(done);
});
it("approvals: allow accounts[1] 100 to withdraw from accounts[0]. Withdraw 60 and then approve 0 & attempt transfer.", function(done) {
var ctr = null;
Standard_Token.new(10000, {from: accounts[0]}).then(function(result) {
ctr = result;
return ctr.approve(accounts[1], 100, {from: accounts[0]});
}).then(function (result) {
return ctr.transferFrom(accounts[0], accounts[2], 60, {from: accounts[1]});
}).then(function (result) {
return ctr.approve(accounts[1], 0, {from: accounts[0]});
}).then(function (result) {
return ctr.transferFrom.call(accounts[0], accounts[2], 10, {from: accounts[1]});
}).then(function (result) {
assert.isFalse(result);
done();
}).catch(done);
});
it("approvals: approve max (2^256 - 1)", function(done) {
var ctr = null;
Standard_Token.new(10000, {from: accounts[0]}).then(function(result) {
ctr = result;
return ctr.approve(accounts[1],'115792089237316195423570985008687907853269984665640564039457584007913129639935' , {from: accounts[0]});
}).then(function (result) {
return ctr.allowance(accounts[0], accounts[1]);
}).then(function (result) {
var match = result.equals('1.15792089237316195423570985008687907853269984665640564039457584007913129639935e+77');
assert.isTrue(match);
done();
}).catch(done);
});
//todo, max approvals.
});
{
"build": "webpack",
"deploy": [
"Standard_Token",
"Standard_Token_Factory"
"HumanStandardToken"
],
"rpc": {
// Default RPC configuration.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment