Business identifier smart contract
Once a business is verified, the accredited issuer who facilities the process will provide the applicant with the address where the contract has been deployed on Redbelly, for example:
0xB52eB569DcDceB64c22095eCCf8BBeAC816Dcd
The contract is used to record and maintain:
- the public details about the business
- a list of public addresses that serve as the businesses authorised representatives
- a list of smart contracts officially associated with your business.
The following is an example of the business identifier contract structure.
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.22;
import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import {AccessControlUpgradeable} from "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
/**
* @title BusinessContract
* @dev A contract that represents a business entity.
*/
contract BusinessIdentifier is AccessControlUpgradeable, UUPSUpgradeable {
/**
* @dev Role identifier for authorized representatives. (Directors or Office holders)
*/
bytes32 public constant AUTHORISED_REPRESENTATIVE_ROLE =
keccak256("AUTHORISED_REPRESENTATIVE");
/**
* @dev Role identifier for authorized delegates. (Contractors, Developers, etc.)
*/
bytes32 public constant AUTHORISED_DELEGATE_ROLE =
keccak256("AUTHORISED_DELEGATE"); // Contractor, Developers, etc..
/**
* @dev The name of the company.
*/
string public companyName;
/**
* @dev The incorporated name of the company.
*/
string public incorporatedName;
/**
* @dev The type of identifier for the company.
*/
string public identifierType;
/**
* @dev The identifier for the company.
*/
string public identifier;
/**
* @dev The business address of the company.
*/
string public businessAddress;
/**
* @dev Boolean indicating if the entity is the beneficial owner of the assets it is managing.
*/
bool public isBeneficialOwner;
/**
* @dev An array storing the addresses of smart contracts owned by the business.
*/
address[] public smartContracts;
error UnauthorisedAccess(string);
error TransferBalanceError(string);
error InvalidAddress(string);
/**
* @dev Initializes the contract with the provided parameters.
* @param _admin The address of the admin account.
* @param _companyName The name of the company.
* @param _incorporatedName The incorporated name of the company.
* @param _identifierType The type of identifier for the company.
* @param _identifier The identifier for the company.
* @param _businessAddress The business address of the company.
* @param _isBeneficialOwner Boolean indicating if the entity is the beneficial owner of the assets it is managing.
*/
function initialize(
address _admin,
string memory _companyName,
string memory _incorporatedName,
string memory _identifierType,
string memory _identifier,
string memory _businessAddress,
bool _isBeneficialOwner
) public initializer {
__AccessControl_init();
__UUPSUpgradeable_init();
// Grant the Admin role to a specified account
_grantRole(DEFAULT_ADMIN_ROLE, _admin);
companyName = _companyName;
incorporatedName = _incorporatedName;
identifierType = _identifierType;
identifier = _identifier;
businessAddress = _businessAddress;
isBeneficialOwner = _isBeneficialOwner;
}
/**
* @dev Event emitted when a smart contract address is added.
* @param _address The address of the smart contract.
* @param _by The address of the caller.
*/
event SmartContractAdded(address indexed _address, address indexed _by);
/**
* @dev Event emitted when a smart contract address is removed.
* @param _address The address of the smart contract.
* @param _by The address of the caller.
*/
event SmartContractRemoved(address indexed _address, address indexed _by);
/**
* @dev Modifier that allows only contract owner to execute a function.
*/
modifier onlyAdmin() {
if (!hasRole(DEFAULT_ADMIN_ROLE, _msgSender())) {
revert UnauthorisedAccess("Caller must have IDP");
}
_;
}
/**
* @dev Modifier that allows only authorized representatives or contract owner to execute a function.
*/
modifier onlyAuthorisedRepresentative() {
if (
!hasRole(DEFAULT_ADMIN_ROLE, _msgSender()) &&
!hasRole(AUTHORISED_REPRESENTATIVE_ROLE, _msgSender())
) {
revert UnauthorisedAccess(
"Caller must have IDP or Authorised Representative"
);
}
_;
}
/**
* @dev Modifier that allows only authorized delegates or authorized representatives or contract owner to execute a function.
*/
modifier onlyAuthorisedDelegte() {
if (
!hasRole(DEFAULT_ADMIN_ROLE, _msgSender()) &&
!hasRole(AUTHORISED_REPRESENTATIVE_ROLE, _msgSender()) &&
!hasRole(AUTHORISED_DELEGATE_ROLE, _msgSender())
) {
revert UnauthorisedAccess(
"Caller must have IDP or Authorised Representative or Authorised Delegate"
);
}
_;
}
/**
* @dev Event emitted when the company name is updated.
* @param _companyName The updated company name.
*/
event UpdatedCompanyName(string _companyName);
/**
* @dev Event emitted when the incorporated name is updated.
* @param _incorporatedName The updated incorporated name.
*/
event UpdatedIncorporatedName(string _incorporatedName);
/**
* @dev Event emitted when the identifier type is updated.
* @param _identifierType The updated identifier type.
*/
event UpdatedIdentifierType(string _identifierType);
/**
* @dev Event emitted when the identifier is updated.
* @param _identifier The updated identifier.
*/
event UpdatedIdentifier(string _identifier);
/**
* @dev Event emitted when the business address is updated.
* @param _businessAddress The updated business address.
*/
event UpdatedBusinessAddress(string _businessAddress);
/**
* @dev Event emitted when the beneficial owner status updated.
* @param _isBeneficialOwner The updated beneficial owner status.
*/
event UpdatedIsBeneficialOwner(bool _isBeneficialOwner);
/**
* @dev Updates the company name.
* @param _companyName The updated company name.
* Requirements:
* - Caller must have the DEFAULT_ADMIN_ROLE.
*/
function updateCompanyName(string memory _companyName) external onlyAdmin {
companyName = _companyName;
emit UpdatedCompanyName(_companyName);
}
/**
* @dev Updates the incorporated name.
* @param _incorporatedName The updated incorporated name.
* Requirements:
* - Caller must have the DEFAULT_ADMIN_ROLE.
*/
function updateIncorporatedName(
string memory _incorporatedName
) external onlyAdmin {
incorporatedName = _incorporatedName;
emit UpdatedIncorporatedName(_incorporatedName);
}
/**
* @dev Updates the identifier type.
* @param _identifierType The updated identifier type.
* Requirements:
* - Caller must have the DEFAULT_ADMIN_ROLE.
*/
function updateIdentifierType(
string memory _identifierType
) external onlyAdmin {
identifierType = _identifierType;
emit UpdatedIdentifierType(_identifierType);
}
/**
* @dev Updates the identifier.
* @param _identifier The updated identifier.
* Requirements:
* - Caller must have the DEFAULT_ADMIN_ROLE.
*/
function updateIdentifier(string memory _identifier) external onlyAdmin {
identifier = _identifier;
emit UpdatedIdentifier(_identifier);
}
/**
* @dev Updates the business address.
* @param _businessAddress The updated business address.
* Requirements:
* - Caller must have the DEFAULT_ADMIN_ROLE.
*/
function updateBusinessAddress(
string memory _businessAddress
) external onlyAdmin {
businessAddress = _businessAddress;
emit UpdatedBusinessAddress(_businessAddress);
}
/**
* @dev Updates the beneficial owner status.
* @param _isBeneficialOwner The updated beneficial owner status.
* Requirements:
* - Caller must have the DEFAULT_ADMIN_ROLE.
*/
function updateIsBeneficialOwner(
bool _isBeneficialOwner
) external onlyAdmin {
isBeneficialOwner = _isBeneficialOwner;
emit UpdatedIsBeneficialOwner(_isBeneficialOwner);
}
/**
* @dev Adds an address as an authorized representative.
* @param _address The address to be added as an authorized representative.
* Requirements:
* - Caller must have the DEFAULT_ADMIN_ROLE.
*/
function addAuthorisedRepresentative(address _address) external onlyAdmin {
_grantRole(AUTHORISED_REPRESENTATIVE_ROLE, _address);
}
/**
* @dev Removes an address as an authorized representative.
* @param _address The address to be removed as an authorized representative.
* Requirements:
* - Caller must have the DEFAULT_ADMIN_ROLE.
*/
function removeAuthorisedRepresentative(
address _address
) external onlyAdmin {
_revokeRole(AUTHORISED_REPRESENTATIVE_ROLE, _address);
}
/**
* @dev Adds an address as an authorized delegate.
* @param _address The address to be added as an authorized delegate.
* Requirements:
* - Caller must be an authorized representative.
*/
function addAuthorisedDelegate(
address _address
) external onlyAuthorisedRepresentative {
_grantRole(AUTHORISED_DELEGATE_ROLE, _address);
}
/**
* @dev Removes an address as an authorized delegate.
* @param _address The address to be removed as an authorized delegate.
* Requirements:
* - Caller must be an authorized representative.
*/
function removeAuthorisedDelegate(
address _address
) external onlyAuthorisedRepresentative {
_revokeRole(AUTHORISED_DELEGATE_ROLE, _address);
}
/**
* @dev Adds a smart contract address to the list of smart contracts owned by the business.
* @param _address The address of the smart contract to be added.
* Requirements:
* - Caller must be an authorized delegate.
* - The provided address must not be the zero address.
*/
function addSmartContract(address _address) external onlyAuthorisedDelegte {
if (_address == address(0)) {
revert InvalidAddress("Invalid address.");
}
smartContracts.push(_address);
emit SmartContractAdded(_address, _msgSender());
}
/**
* @dev Removes a smart contract address from the list of smart contracts owned by the business.
* @param _address The address of the smart contract to be removed.
* Requirements:
* - Caller must be an authorized delegate.
*/
function removeSmartContract(
address _address
) external onlyAuthorisedDelegte {
for (uint256 i = 0; i < smartContracts.length; i++) {
if (smartContracts[i] == _address) {
smartContracts[i] = smartContracts[smartContracts.length - 1];
smartContracts.pop();
break;
}
}
emit SmartContractRemoved(_address, _msgSender());
}
/**
* @dev Internal function to authorize an upgrade to a new implementation.
* @param newImplementation The address of the new implementation contract.
* Requirements:
* - Caller must have the DEFAULT_ADMIN_ROLE.
*/
function _authorizeUpgrade(
address newImplementation
) internal override onlyRole(DEFAULT_ADMIN_ROLE) {}
}
Interacting with a deployed business identifier contract
![remix](https://vine.redbelly.network/hs-fs/hubfs/vine/images/remix.jpeg?width=400&height=400&name=remix.jpeg)
2. Setup contract
- Connect to Remix with the public address your provided the accredited issuer when you registered.
- Import the BusinessIdentifier.sol contract template.
- Compile the contract using the Solidity Compiler feature.
![remix-compiler-example](https://vine.redbelly.network/hs-fs/hubfs/vine/images/remix-compiler-example.png?width=1184&height=889&name=remix-compiler-example.png)
3. Connect to the deployed instance
- Remix will allow you to select "injected provider" from it's Deploy and Run Transactions tab.
- Paste the contract address of the specific deployed instance of the contract you want to interact with using the At Address feature.
![remix-inject-example](https://vine.redbelly.network/hs-fs/hubfs/vine/images/remix-inject-example.png?width=677&height=760&name=remix-inject-example.png)
4. Utilise specific functions
Once Remix has been connected to the deployed version of the contract, it will display a list of available functions (see below).
These functions can be utilised through the Remix interface. For example, to add a smart contract to the smartContracts array, the contract address is entered into the addsmartContract input field.
Once the transaction is made and the payload is signed through the connected wallet, the contract will update.
Functions and roles
The following is a list of functions available to representatives of the business in the BusinessIdentifier smart contract.
The following roles are associated with the smart contract management:
- Authorised representative (director of the business)
- Authorised delegate (any official associated party of the business)
Managing roles
Function | Description | Update requirement role |
addAuthorisedDelegate | Grants the AUTHORISED_DELEGATE_ROLE to an address. | Authorised representative only |
removeAuthorisedDelegate | Revokes the AUTHORISED_DELEGATE_ROLE from an address | Authorised representative only |
Managing smart contracts
Function | Description | Update requirement role |
addSmartContract | Adds a smart contract address to the smartContracts array. | Authorised representative or Authorised delegate |
removeSmartContract | Removes a smart contract address from the smartContracts array. | Authorised representative or Authorised delegate |
Updating business profile
To protect the integrity of the official information on-chain, updating the fundamental details about a business (which were verified before the business smart contract was generated) requires re-verification of the business.
To do so, raise a request with the accredited issuer who created the business smart contract, detailing the required changes to the BusinessIdentifier smart contract.
This includes if the need arises to:
- update the company name
- update the incorporated name
- update identifier type
- update identifier
- update the business address
- update the beneficial owner
- add a company director
- remove a company director