appliedblockchain / cobalt Goto Github PK
View Code? Open in Web Editor NEWFast, lightweight ethereum dapp prototyping
License: MIT License
Fast, lightweight ethereum dapp prototyping
License: MIT License
When using web3.require to compile solidity contracts with the following
web3.require('./validators/OwnedSet.sol')
I'm get the following error:
The OwnerSet.sol
contract imports an interface contract which may be causing this error. Upon investigation, it looks like web3-require.js
does a check on the bytecode and throw error if it is not in the correct format. In my case, the error is caused by the empty bytecode on interface methods.
However, this seems to be the expected output when compiling an interface. I tried compiling the contract with the following command
solc --combined-json abi,bin ./contracts/validators/OwnedSet.sol > out.json
And I get the following output:
{
"contracts": {
"./contracts/validators/OwnedSet.sol:OwnedSet": {
"abi": "[{\"constant\":true,\"inputs\":[],\"name\":\"recentBlocks\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getPending\",\"outputs\":[{\"name\":\"\",\"type\":\"address[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_new\",\"type\":\"address\"}],\"name\":\"setOwner\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_validator\",\"type\":\"address\"}],\"name\":\"removeValidator\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_validator\",\"type\":\"address\"}],\"name\":\"addValidator\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"finalizeChange\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_recentBlocks\",\"type\":\"uint256\"}],\"name\":\"setRecentBlocks\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"finalized\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getValidators\",\"outputs\":[{\"name\":\"\",\"type\":\"address[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_validator\",\"type\":\"address\"},{\"name\":\"_blockNumber\",\"type\":\"uint256\"},{\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"reportMalicious\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_validator\",\"type\":\"address\"},{\"name\":\"_blockNumber\",\"type\":\"uint256\"}],\"name\":\"reportBenign\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"_initial\",\"type\":\"address[]\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"reporter\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"reported\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"malicious\",\"type\":\"bool\"}],\"name\":\"Report\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"current_set\",\"type\":\"address[]\"}],\"name\":\"ChangeFinalized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"_parent_hash\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"_new_set\",\"type\":\"address[]\"}],\"name\":\"InitiateChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"old\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"current\",\"type\":\"address\"}],\"name\":\"NewOwner\",\"type\":\"event\"}]",
"bin": "6060604052336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550601460015534156200005557600080fd5b604051620013343803806200133483398101604052808051820191905050600081600390805190602001906200008d9291906200019d565b50600090505b600182510381101562000180576001600460008484815181101515620000b557fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548160ff021916908315150217905550806004600084848151811015156200012757fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010181905550808060010191505062000093565b60036002908054620001949291906200022c565b505050620002c9565b82805482825590600052602060002090810192821562000219579160200282015b82811115620002185782518260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555091602001919060010190620001be565b5b50905062000228919062000283565b5090565b828054828255906000526020600020908101928215620002705760005260206000209182015b828111156200026f57825482559160010191906001019062000252565b5b5090506200027f919062000283565b5090565b620002c691905b80821115620002c257600081816101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055506001016200028a565b5090565b90565b61105b80620002d96000396000f3006060604052600436106100ba576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630c857805146100bf57806311ae9ed2146100e857806313af40351461015257806340a141ff1461018b5780634d238c8e146101c457806375286211146101fd5780638c90ac07146102125780638da5cb5b14610235578063b3f05b971461028a578063b7ab4db5146102b7578063c476dd4014610321578063d69f13bb146103a6575b600080fd5b34156100ca57600080fd5b6100d26103e8565b6040518082815260200191505060405180910390f35b34156100f357600080fd5b6100fb6103ee565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b8381101561013e578082015181840152602081019050610123565b505050509050019250505060405180910390f35b341561015d57600080fd5b610189600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610482565b005b341561019657600080fd5b6101c2600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061059b565b005b34156101cf57600080fd5b6101fb600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610837565b005b341561020857600080fd5b610210610a05565b005b341561021d57600080fd5b6102336004808035906020019091905050610b1a565b005b341561024057600080fd5b610248610b7f565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561029557600080fd5b61029d610ba4565b604051808215151515815260200191505060405180910390f35b34156102c257600080fd5b6102ca610bb7565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b8381101561030d5780820151818401526020810190506102f2565b505050509050019250505060405180910390f35b341561032c57600080fd5b6103a4600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050610c4b565b005b34156103b157600080fd5b6103e6600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610d1e565b005b60015481565b6103f6610f09565b600380548060200260200160405190810160405280929190818152602001828054801561047857602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001906001019080831161042e575b5050505050905090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156104dd57600080fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f70aea8d848e8a90fb7661b227dc522eb6395c3dac71b63cb59edd5c9899b236460405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156105f657600080fd5b80600460008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff16151561065257600080fd5b600360016003805490500381548110151561066957fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166003600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101548154811015156106e657fe5b906000526020600020900160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600360016003805490500381548110151561074657fe5b906000526020600020900160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905560038054809190600190036107899190610f1d565b50600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101600090556000600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548160ff021916908315150217905550610833610e48565b5050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561089257600080fd5b80600460008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff161515156108ef57600080fd5b6001600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548160ff021916908315150217905550600380549050600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010181905550600380548060010182816109aa9190610f49565b9160005260206000209001600084909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050610a01610e48565b5050565b73fffffffffffffffffffffffffffffffffffffffe73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141580610a605750600560009054906101000a900460ff165b1515610a6b57600080fd5b60036002908054610a7d929190610f75565b506001600560006101000a81548160ff0219169083151502179055507f8564cd629b15f47dc310d45bcbfc9bcf5420b0d51bf0659a16c67f91d2763253610ac2610bb7565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610b05578082015181840152602081019050610aea565b505050509050019250505060405180910390a1565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610b7557600080fd5b8060018190555050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600560009054906101000a900460ff1681565b610bbf610f09565b6002805480602002602001604051908101604052809291908181526020018280548015610c4157602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610bf7575b5050505050905090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610ca657600080fd5b8160015481014311151515610cba57600080fd5b600115158473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f32c78b6140c46745a46e88cd883707d70dbd2f06d13dd76fe5f499c01290da4f60405160405180910390a450505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610d7957600080fd5b81600460008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff1615610e43578160015481014311151515610de357600080fd5b600015158473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f32c78b6140c46745a46e88cd883707d70dbd2f06d13dd76fe5f499c01290da4f60405160405180910390a4505b505050565b600560009054906101000a900460ff16151515610e6457600080fd5b6000600560006101000a81548160ff0219169083151502179055506001430340600019167f55252fa6eee4741b4e24a74a70e9c11fd2c2281df8d6ea13126ff845f7825c89610eb16103ee565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610ef4578082015181840152602081019050610ed9565b505050509050019250505060405180910390a2565b602060405190810160405280600081525090565b815481835581811511610f4457818360005260206000209182019101610f439190610fc7565b5b505050565b815481835581811511610f7057818360005260206000209182019101610f6f9190610fc7565b5b505050565b828054828255906000526020600020908101928215610fb65760005260206000209182015b82811115610fb5578254825591600101919060010190610f9a565b5b509050610fc39190610fec565b5090565b610fe991905b80821115610fe5576000816000905550600101610fcd565b5090565b90565b61102c91905b8082111561102857600081816101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550600101610ff2565b5090565b905600a165627a7a72305820d44eded361504e65c8b6ea521fe3032ff83fa5b2e6316c9a8bbaaec1b43df04d0029"
},
"./contracts/validators/interfaces/Owned.sol:Owned": {
"abi": "[{\"constant\":false,\"inputs\":[{\"name\":\"_new\",\"type\":\"address\"}],\"name\":\"setOwner\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"old\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"current\",\"type\":\"address\"}],\"name\":\"NewOwner\",\"type\":\"event\"}]",
"bin": "6060604052336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550341561004f57600080fd5b6102498061005e6000396000f30060606040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806313af4035146100515780638da5cb5b1461008a575b600080fd5b341561005c57600080fd5b610088600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506100df565b005b341561009557600080fd5b61009d6101f8565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561013a57600080fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f70aea8d848e8a90fb7661b227dc522eb6395c3dac71b63cb59edd5c9899b236460405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff16815600a165627a7a723058202e75a8bd2563eb687d3e1225909507753e95433368ac628da8c1425f21baf6360029"
},
"./contracts/validators/interfaces/ValidatorSet.sol:ImmediateSet": {
"abi": "[{\"constant\":false,\"inputs\":[],\"name\":\"finalizeChange\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getValidators\",\"outputs\":[{\"name\":\"\",\"type\":\"address[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"validator\",\"type\":\"address\"},{\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"name\":\"proof\",\"type\":\"bytes\"}],\"name\":\"reportMalicious\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"validator\",\"type\":\"address\"},{\"name\":\"blockNumber\",\"type\":\"uint256\"}],\"name\":\"reportBenign\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"_parent_hash\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"_new_set\",\"type\":\"address[]\"}],\"name\":\"InitiateChange\",\"type\":\"event\"}]",
"bin": ""
},
"./contracts/validators/interfaces/ValidatorSet.sol:SafeValidatorSet": {
"abi": "[{\"constant\":false,\"inputs\":[],\"name\":\"finalizeChange\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getValidators\",\"outputs\":[{\"name\":\"\",\"type\":\"address[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"\",\"type\":\"address\"},{\"name\":\"\",\"type\":\"uint256\"},{\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"reportMalicious\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"\",\"type\":\"address\"},{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"reportBenign\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"_parent_hash\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"_new_set\",\"type\":\"address[]\"}],\"name\":\"InitiateChange\",\"type\":\"event\"}]",
"bin": ""
},
"./contracts/validators/interfaces/ValidatorSet.sol:ValidatorSet": {
"abi": "[{\"constant\":false,\"inputs\":[],\"name\":\"finalizeChange\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getValidators\",\"outputs\":[{\"name\":\"\",\"type\":\"address[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"validator\",\"type\":\"address\"},{\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"name\":\"proof\",\"type\":\"bytes\"}],\"name\":\"reportMalicious\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"validator\",\"type\":\"address\"},{\"name\":\"blockNumber\",\"type\":\"uint256\"}],\"name\":\"reportBenign\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"_parent_hash\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"_new_set\",\"type\":\"address[]\"}],\"name\":\"InitiateChange\",\"type\":\"event\"}]",
"bin": ""
}
},
"version": "0.4.21+commit.dfe3193c.Darwin.appleclang"
}
The workaround for me right now is to temporary comment out the throwOnAmbiguousPlaceholders
check at web3-require.js:54
. Looks like we may need to add a conditional check to allow for empty bytecodes to support interfaces?
Please see the source for the contracts attached as txt files:
OwnedSet.txt
ValidatorSet.txt
Owned.txt
Similar to what truffles allow, it would be nice to be able to import contracts that are located in the node_modules folder rather than having to copy them over inside of the contract path.
ex:
import "@appliedblockchain/trufflib/libraries/Sig.sol";
where "@appliedblockchain/trufflib" is an installed node module
There are probably some other concerns, but a couple of notable ones:
apt
or similar instructions in the readmeconst { web3, accounts } = require('../lib/web3')({
root: `${__dirname}/../contracts`
})
should be changed to:
const { join } = require('path')
const { web3, accounts } = require('../web3')({
root: join(__dirname, '..', 'contracts')
})
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.