I'd like to create a private network where I would limit the creation of smart contracts to a whitelist of accounts. Is there any option for this?
2 Answers
Yes, it is possible to limit the creation of contracts to whitelisted accounts. I did this in a public permissioned blockchain with PoA and based on parity node Ethereum clients.
The only thing you need is a smart contract and two entries in the spec.json file. It is possible to grant here rights in a fine granular way to accounts.
Contract to manage access
Your contract code should look like this (Source https://gitlab.com/ihk-muenchen/open-ethereum-hash-manager):
pragma solidity 0.5.17;
import "./openzeppelin/access/roles/WhitelistedRole.sol";
// @title Manages transaction on the network
contract TransactionType is WhitelistedRole {
// ---- EVENTS ----------------------------------------------------------------------------------------------------
event ConstructorDone(address _creator, string version);
// ---- FIELDS -----------------------------------------------------------------------------------------------------
/// Allowed transaction types mask
uint32 private constant NONE = 0;
uint32 private constant BASIC = 0x01;
uint32 private constant CALL = 0x02;
uint32 private constant CREATE = 0x04;
uint32 private constant ALL = 0x0f;
// ---- CONSTRUCTOR ------------------------------------------------------------------------------------------------
constructor() public {
addWhitelisted(msg.sender); // deployment account
emit ConstructorDone(msg.sender, "4.0.0");
}
// ---- FUNCTIONS -------------------------------------------------------------------------------------------------
function allowedTxTypes(address user) public view returns (uint32) {
if (isWhitelisted(user)) {
return ALL;
}
return CALL | BASIC; //contract calls and Eth transfers allowed.
}
}
Deploy this contract to the blockchain and add call addWhitelisted() with accounts you like to enable.
Blockchain Specification
Then you need to add the contract address to your spec.json like this:
...
"params": {
"transactionPermissionContract": "0xccc768B2691720fd4ba5aA7058Bd992Ee074cA10",
"transactionPermissionContractTransition": "0x32"
},
...
Replace the value of contract address (here 0xccc768B2691720fd4ba5aA7058Bd992Ee074cA10) with your own value. Set the starting block with the hex number in transactionPermissionContractTransition (here block number 50).
Find more information at https://openethereum.wiki/Permissioning/#transaction-type
Disclaimer
I'm not 100% sure that this also works with Rinkeby Clique PoA - but quite confident. The described solution had been implemented and tested with a single Ethereum client network. We started to work on multi Ethereum client solutions, but stopped because there had been some limitations in the configuration that turned out to be show stoppers for your specific requirements.
I think you could achieve this by only pre-funding the accounts you want to be able to create contracts with Ether when you set up your network- Puppeth gives you the option to do this when you create your genesis block.
Creating a contract burns gas, so only accounts with funds in your network could create contracts.