ludis@MacBook ~ cd Desktop/contract ludis@MacBook ~ /Desktop/contract npm init This utility will walk you through creating a package.json file. It only covers the most common items, and tries to guess sensible defaults.
See `npm help json` for definitive documentation on these fields and exactly what they do.
Use `npm install <pkg>` afterwards to install a package and save it as a dependency in the package.json file.
Press ^C at any time to quit. package name: (contract) version: (1.0.0) description: entry point: (index.js) test command: git repository: keywords: author: license: (ISC) About to write to /Users/ludis/Desktop/contract/package.json:
ludis@MacBook ~/Desktop/test ipfs get QmZ5cRqiNsg1ngmzmKrv5STMoyfLaJhhHqXyMWTkre1qte Saving file(s) to QmZ5cRqiNsg1ngmzmKrv5STMoyfLaJhhHqXyMWTkre1qte 20 B / 20 B [========================================] 100.00% 0s
mapping(address => Message[]) public words; // 以字典形式存储
// 写入留言 function setWord(string s, string t) public { if(words[msg.sender].length==0) { addrArr.push(msg.sender); } words[msg.sender].push(Message({ word: s, time: t })); }
// 获取某地址对应的所有留言(获取我的所有留言) function getWordByAddress() public view returns (Message[]) { return words[msg.sender]; }
// 随机返回十条留言 function getRandomWord() public view returns (Message[]) { Message[] memory result; for w, i := range words { result.push(w) if(i==9) break; } return result; }
第二句import SimpleStorageContract from '../build/contracts/SimpleStorage.json'导入的实际上是上步合约代码编译后产生的json文件,该文件中包含两个重要信息:一个是abi字段,通俗讲就是合约代码编译后产生的二进制接口,其中会声明合约代码暴露的可供调用的接口;另一个是bytecode字段,为合约代码的十六进制码。通过这两个重要信息就可以对一个合约进行相应操作。
instantiateContract() { /* * SMART CONTRACT EXAMPLE * * Normally these functions would be called in the context of a * state management library, but for convenience I've placed them here. */
// Stores a given value, 5 by default. // return simpleStorageInstance.set(5, {from: accounts[0]}) return; }).then((result) => { // Get the value from the contract to prove it worked. return simpleStorageInstance.get.call(accounts[0]) }).then((result) => { // Update state with the result. console.log(result); returnthis.setState({ storageValue: result.c[0] }) }) }) }
render() { return ( <divclassName="App"> <navclassName="navbar pure-menu pure-menu-horizontal"> <ahref="#"className="pure-menu-heading pure-menu-link">Truffle Box</a> </nav> <mainclassName="container"> <divclassName="pure-g"> <divclassName="pure-u-1-1"> <h1>Good to Go!</h1> <p>Your Truffle Box is installed and ready.</p> <h2>Smart Contract Example</h2> <p>If your contracts compiled and migrated successfully, below will show a stored value of 5 (by default).</p> <p>Try changing the value stored on <strong>line 59</strong> of App.js.</p> <p>The stored value is: {this.state.storageValue}</p> </div> </div> </main> <inputref="myvalue"className="myinput"/> <button className="mybutton" onClick={() => { var num = Number(this.refs.myvalue.value); console.log("点击了button"); console.log(num); simpleStorageInstance.set(num, {from: this.state.web3.eth.accounts[0]}).then(() => { console.log("数据修改成功"); simpleStorageInstance.get.call(this.state.web3.eth.accounts[0]).then((result) => { console.log("数据读取成功"); console.log(result); // 修改状态变量的值,在react中,一旦状态变量的值发生变化,就会调用render函数重新渲染UI this.setState({ storageValue: result.c[0] }) }); }) }} style={{height: 40,marginLeft: 50}}>修改合约数据</button> </div> ); } }
在Ropsten Test Network测试网络下,点击BUY->ROPSTEN TEST FAUCET会跳转到https://faucet.metamask.io/页面,可以请求获取测试用的eth代币,也可以给别人发送测试代币。操作完成后钱包会显示相应的测试代币数量。
在Kovan Test Network测试网络下,获取测试代币的方式是:加入gitter中的faucet组织,链接为https://gitter.im/kovan-testnet/。加入后,MateMask钱包在Kovan Test Network测试网络下,复制当前测试环境下的钱包地址,然后在gitter的社区中,发送自己的钱包地址(@管理员epheph),这位雷锋大兄弟会给你的钱包发送5个测试代币,最后别忘了来句日常感谢~
// construct 关键字声明类 contract Person { uint age = 0; // 默认类型为internal string internal name = "佩奇"; string public homeAddress = "北京市朝阳区"; // public声明的属性,会自动生成同名的get函数,返回该属性值 string private company = "孔壹学院"; // 构造函数,与类名同名,首次初始化时调用 function Person() public { age = 18; } // set方法 function setCompany(uint a) public { age = a; } // get方法 function getCompany() view public returns (uint) { return age; } function getCurrentAddres() view public returns (address) { // msg.sender 返回当前操作合约的钱包的地址 return msg.sender; } // 普通函数 function kill() public{ // 析构函数,调用时销毁当前合约 selfdestruct(msg.sender); } }
contract ChildPerson is Person { function test() public { age = 100; name = "AWM"; } }
c := make(chanint) done := make(chanbool) n := 10 // 生产者:大黄 gofunc() { for i := 0; i < 100; i++ { fmt.Println("生成者生产数据:", i) c <- i } close(c) }()
for i := 0; i < n; i++ { // 消费者:小明 gofunc(idx int) { // range 会一直不断检测c管道中的数据,如果有,读取,否则等待,直到显示的close关闭通道 for n := range c { fmt.Println("消费者",idx,"消费数据:", n) } done <- true }(i) }
func main() { // c是一个管道 c := incrementor() //把管道作为返回值 cSum := puller(c) //把管道作为参数 for n := range cSum { fmt.Println(n) // 0 ...9 } }
// 类型:func () chan int // chan int 返回值类型 func incrementor() chan int { // 创建一个管道 out := make(chan int) // 通过主线程创建一个分线程 go func() { //子线程 for i := 0; i < 10; i++ { out <- i //生产数据 } close(out) }() // 返回out管道 return out }
// 函数类型:func (chan int) chan int // 返回值类型:chan int // 参数类型:chan int func puller(c chan int) chan int { // 创建一个新的管道 out := make(chan int) // 创建一个子线程 go func() { var sum int
// <-c // 通过range取读取管道c里面的数据,这个for跳出循环的时间为管道c被关闭 for n := range c { sum += n }
// out <- sum 什么时候执行? out <- sum //生产者 close(out) }() return out }
3、单向管道、双向管道
双向通道: 前面我们以var c chan int形式声明的通道,即类型为chan type的channel都是双向通道。双向通道顾名思义,就是能存数据又能读数据 单向通道: 单向通道,就是只能存或只能读的channel 声明单向通道:
1 2 3 4 5
var readChan <-chan int // 只读的channel var c WriteChan<- int // 只写的channel